/* ============================================================
   TO TOP  —  the way back from the end of the page

   Appears once the reader has reached the foot of the document and
   takes them back to the hero. Hidden the rest of the time, so it
   is not a permanent widget parked over the content.

   WHERE IT SITS, AND WHY NOT BESIDE THE DOCK

   The dock is fixed to the bottom centre. At 320px it is 276px
   wide, which leaves about 22px of clear page on each side — not
   room for a 44px target. So this sits ABOVE the dock rather than
   next to it, offset by the dock's own height and gap so the two
   never overlap at any width. Both read from the same tokens, so
   resizing the dock moves this with it.

   `inset-inline-start` is the physical RIGHT in this RTL document
   — the opposite corner from the theme toggle, which uses
   `inset-inline-end` and lands on the left.

   NOT `position: sticky`, NOT A SCROLL LISTENER

   Visibility is driven from the same scroll engine every other
   effect on the page uses, via a class. A `:has()` or IntersectionObserver
   variant would work too, but this keeps the one-read-per-frame
   discipline the rest of the site holds to.
   ============================================================ */

.to-top {
  position: fixed;
  /* Clear of the dock: its height, its gap from the bottom, and a
     gap of our own. */
  inset-block-end: calc(var(--dock-h) + var(--dock-gap) + var(--sp-md));
  inset-inline-start: clamp(1rem, 2.5vw, 2rem);
  z-index: var(--z-menu-btn);

  display: grid;
  place-items: center;
  inline-size: 46px;
  block-size: 46px;
  padding: 0;

  border-radius: var(--r-pill);
  border: 1px solid rgb(var(--rgb-shine) / 0.22);

  /* The same glass as the theme toggle, at the same strength — the
     two are the site's only floating controls and reading as one
     family matters more than either being individually tuned. */
  background-color: rgb(var(--rgb-media) / 0.42);
  background-image: linear-gradient(145deg,
                      rgb(var(--rgb-shine) / 0.22) 0%,
                      rgb(var(--rgb-shine) / 0.06) 42%,
                      rgb(var(--rgb-shadow) / 0.10) 100%);
  -webkit-backdrop-filter: blur(22px) saturate(1.6);
  backdrop-filter: blur(22px) saturate(1.6);
  box-shadow:
    0 14px 30px rgb(var(--rgb-shadow) / 0.38),
    inset  1.5px  1.5px 2px rgb(var(--rgb-shine) / 0.30),
    inset -1.5px -1.5px 3px rgb(var(--rgb-shadow) / 0.22);

  color: var(--c-on-media);
  cursor: pointer;

  /* Hidden state. `visibility` as well as opacity, so the button
     leaves the tab order when it is not on screen — an invisible
     control that still takes focus is worse than no control. */
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px) scale(0.9);
  transition:
    opacity    var(--dur-base) var(--ease),
    transform  var(--dur-base) var(--ease-out),
    visibility 0s linear var(--dur-base),
    border-color var(--dur-base) var(--ease);
}

.to-top.is-shown {
  opacity: 1;
  visibility: visible;
  transform: translateY(0) scale(1);
  transition-delay: 0s;
}

.to-top:hover {
  border-color: rgb(var(--rgb-ink) / 0.45);
}

.to-top:focus-visible {
  outline: 2px solid var(--c-on-media);
  outline-offset: 3px;
}

.to-top svg {
  inline-size: 20px;
  block-size: 20px;
}

@media (prefers-reduced-motion: reduce) {
  .to-top {
    transition-duration: 1ms;
    transform: none;
  }
  .to-top.is-shown { transform: none; }
}
