/* ==========================================================================
   Being shown around.

   The dark is one huge box-shadow spread out of a ring that sits exactly on
   the thing being explained. Four dimming panels around a hole would leave
   hairline seams where they meet, and no four rectangles can round a corner —
   a pill button in a rectangular hole reads as a bug, not as a spotlight.

   Only tokens from styles.css, so Light, Dark and Auto all come out right on
   their own. The one colour that isn't a token is the dark itself, and that is
   a light-dark() pair at the bottom of the file: the daytime half is in the
   rule above, so an older Safari still gets a usable scrim rather than an
   invalid declaration and no dimming at all.
   ========================================================================== */

/* The printed page is the product. None of this ever belongs on paper — and
   she may well reach for Print while a tour is still open. */
@media print {
  .tour { display: none !important; }
}

/*
 * Above everything, including the photo viewer and the camera at 300. A
 * spotlight that something else paints over is no longer a spotlight.
 *
 * The whole surface catches taps: on the dark, and on the lit thing as well.
 * Letting a tap through to the control underneath would start something she
 * cannot see the beginning of, and there has to be a way out from anywhere.
 */
.tour {
  position: fixed; inset: 0; z-index: 400;
  -webkit-tap-highlight-color: transparent;
  --tour-dim: rgba(31, 58, 95, .62);
}

/* Where the bubble is allowed to be. An element rather than arithmetic in JS,
   so the real safe-area insets are read off the browser instead of guessed —
   an iPad in landscape has a home indicator along one edge and nothing along
   the other three. */
.tour__safe {
  position: absolute; pointer-events: none;
  top: max(12px, env(safe-area-inset-top));
  right: max(12px, env(safe-area-inset-right));
  bottom: max(12px, env(safe-area-inset-bottom));
  left: max(12px, env(safe-area-inset-left));
}

/* The opening card of every tour explains the screen rather than any one thing
   on it, so there is nothing to cut a hole for and the dark is laid on flat. */
.tour--plain { background: var(--tour-dim); }

/*
 * 120vmax rather than 100: 100 is exactly enough only when the ring is hard
 * against an edge, and the margin costs nothing.
 *
 * The thin accent ring is painted from the same shadow list. Earlier shadows
 * sit on top of later ones, so it lands over the dark rather than under it.
 *
 * The tint on that ring is behind a feature query, and it has to be — writing
 * the declaration out twice, plain then tinted, does NOT work here and is worth
 * spelling out because it looks like it should.
 *
 * That trick only rescues the first declaration when the second is invalid at
 * PARSE time. Both of these carry `var()`, and a declaration containing a
 * syntactically valid `var()` is assumed valid at parse time and grammar-checked
 * only after substitution. So on a browser without color-mix() the tinted line
 * still wins the cascade, then fails at computed-value time — which sets the
 * property to `unset`, not back to the line above it. box-shadow doesn't
 * inherit, so it computes to `none`: no ring AND no dark, leaving a card
 * floating over a lit, tappable page. Measured, not assumed.
 *
 * @supports asks the question properly. Same reason the light-dark() block at
 * the bottom of this file exists.
 */
.tour__ring {
  position: fixed; pointer-events: none;
  box-shadow:
    0 0 0 3px var(--accent),
    0 0 0 120vmax var(--tour-dim);
}

@supports (color: color-mix(in srgb, red 50%, transparent)) {
  .tour__ring {
    box-shadow:
      0 0 0 3px color-mix(in srgb, var(--accent) 60%, transparent),
      0 0 0 120vmax var(--tour-dim);
  }
}

/* ── The bubble ────────────────────────────────────────────────────────── */

.tour__bubble {
  position: fixed;
  width: min(21rem, calc(100vw - 1.5rem));
  padding: 1rem 1.15rem 1.1rem;
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--card); color: var(--ink);
  box-shadow: var(--shadow-lg);
}

/* A rotated square with two of its borders, so it takes the bubble's edge with
   it. Its position along that edge is set in JS — it points at the target even
   after the bubble has been clamped away from it. */
.tour__arrow {
  position: absolute; width: 12px; height: 12px;
  background: var(--card); border: 1px solid var(--rule);
  transform: rotate(45deg);
}
.tour__bubble[data-at="bottom"] .tour__arrow { top: -7px; border-width: 1px 0 0 1px; }
.tour__bubble[data-at="top"] .tour__arrow { bottom: -7px; border-width: 0 1px 1px 0; }
.tour__bubble[data-at="right"] .tour__arrow { left: -7px; border-width: 0 0 1px 1px; }
.tour__bubble[data-at="left"] .tour__arrow { right: -7px; border-width: 1px 1px 0 0; }
.tour__bubble[data-at="none"] .tour__arrow { display: none; }

.tour__count {
  margin: 0 0 .2rem;
  font-size: .72rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--ink-faint);
}
/* A one-step tour has nothing to count, and an empty line above the heading
   looks like something failed to load. */
.tour__count:empty { display: none; }

.tour__title { font-family: var(--serif); font-size: 1.15rem; margin: 0 0 .35rem; }
.tour__body { margin: 0; color: var(--ink-soft); font-size: .95rem; line-height: 1.5; }

.tour__foot {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: .5rem; margin-top: 1rem;
}
.tour__gap { flex: 1 1 auto; }

/* Specificity a notch above .btn, so this behaves the same whichever side of
   styles.css its <link> lands on. */
.tour__bubble .btn { flex: none; }

/* Read out on every step. Never seen — the bubble already says all of it, and
   showing it twice would be showing it twice. */
.tour__live {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── Movement ──────────────────────────────────────────────────────────── */

/*
 * The light glides from one thing to the next; the bubble doesn't follow it
 * across the screen, it fades in where it is wanted. A bubble sliding as well
 * is two things moving at once, and the eye ends up watching the furniture
 * rather than the thing being pointed at.
 *
 * Only while stepping — track() takes the class off the moment the page
 * scrolls, because a glide racing a scroll only ever loses.
 */
.tour--gliding .tour__ring {
  transition: top .22s ease, left .22s ease, width .22s ease, height .22s ease;
}

@keyframes tour-in { from { opacity: 0; transform: translateY(6px); } }
.tour__bubble--in { animation: tour-in .18s ease-out; }

@media (prefers-reduced-motion: reduce) {
  .tour--gliding .tour__ring { transition: none; }
  .tour__bubble--in { animation: none; }
}

/* ── Touch ─────────────────────────────────────────────────────────────── */

/*
 * `any-pointer: coarse`, not `hover: none`. An iPad in a Magic Keyboard
 * reports `hover: hover`, so sizing keyed on hover switches itself off on the
 * one device this app is really used on. Nothing here is revealed by hovering
 * in any case — all three buttons are always there.
 */
@media (any-pointer: coarse) {
  .tour__bubble {
    width: min(23rem, calc(100vw - 1.5rem));
    padding: 1.15rem 1.25rem 1.2rem;
  }
  .tour__bubble .btn { min-height: 44px; }
  .tour__title { font-size: 1.2rem; }
  .tour__body { font-size: 1rem; }
}

/* An iPhone held upright, where three buttons on one line get tight. */
@media (max-width: 380px) {
  .tour__gap { display: none; }
  .tour__bubble .btn { flex: 1 1 auto; }
}

/*
 * The same colour again, as a light-dark() pair.
 *
 * The rule above now carries only the daytime value, which every browser
 * understands; this block adds the evening half where light-dark() is
 * supported. Without the guard the declaration is simply invalid on an older
 * Safari — and an invalid colour inherits, which for a scrim means no scrim.
 *
 * It is deliberately not --ink at some opacity: --ink turns near-white after
 * dark, so that would light the room up instead of dimming it.
 */
@supports (color: light-dark(#000, #fff)) {
  .tour { --tour-dim: light-dark(rgba(31, 58, 95, .62), rgba(4, 9, 15, .74)); }
}
