/* to-top.css - the back-to-top control. Pair with js/to-top.js.

   IT IS A .btn, NOT A BESPOKE CIRCLE. The first version of this file drew its
   own round shape, its own hover colour with a color-mix, and its own focus
   ring - three inventions where base.css already had three declarations, and
   three things that would not follow the system the next time any of them
   changed. The markup now carries `btn btn-fill btn-on-dark to-top` and this
   sheet overrides four properties: where it sits, that it is square, that it
   has no padding, and that it fades in. Everything else - the wipe, the lift,
   the press, the ring - is inherited and therefore cannot drift.

   THE SHAPE COMES OUT OF THE TOKEN. --r-pill is 24px and the box is 48px, so
   --r-pill IS the circle here; the browser clamps the radius to half the box,
   which is also why the 44px phone size stays round without a second value.
   border-radius:50% would render identically and the site uses it freely for
   dots and avatars - but those are shapes that are round BECAUSE they are dots.
   This is a pill-radius control that happens to be square, so it takes the
   token, and it stays correct if --r-pill is ever retuned.

   WHY btn-on-dark AND NOT btn-neutral. base.css states the rule: purple is the
   network, black is everything else, and an in-page utility takes neutral. But
   neutral is --ink, and this control's whole job happens at the BOTTOM of the
   page - which on all thirteen pages is the dark footer. A --ink circle over
   the footer is invisible at the exact moment it is wanted. .btn-on-dark is a
   white face with a --plum mark and a --lavender wipe: it reads on the white
   read, on the offwhite bands, and on the footer. It is also still not purple,
   so the network rule holds. */
.to-top{
  position:fixed;right:var(--s6);bottom:var(--s6);z-index:var(--z-dropdown);
  width:48px;height:48px;padding:0;
  display:grid;place-items:center;
  border-radius:var(--r-pill);
  box-shadow:var(--e-high);

  /* HIDDEN WITH visibility, NOT display OR [hidden]. Both of those would kill
     the fade, but the part that actually matters is that visibility:hidden also
     takes it out of the tab order - a control nobody can see must not be the
     next thing focus lands on. The delay on the visibility leg lets the opacity
     finish before it goes.

     THE ENTRY IS A FADE AND NOTHING ELSE. A rise or a scale would have to be
     written on `transform`, which is the property .btn-fill's lift and press
     already own; the two would overwrite each other and the button would stop
     answering the cursor. Opacity is the one channel free to carry this. */
  opacity:0;visibility:hidden;
  transition:background-color 200ms ease-in-out,color 200ms ease-in-out,
             transform 180ms var(--ease),box-shadow 220ms var(--ease),
             opacity 200ms ease-in-out,visibility 0s linear 200ms;
}
.to-top.is-in{opacity:1;visibility:visible;transition-delay:0s}

/* The chevron. currentColor, so it takes .btn-on-dark's --plum and whatever the
   wipe leaves behind, rather than naming a colour this sheet would then own. */
.to-top svg{
  width:18px;height:18px;fill:none;stroke:currentColor;
  stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;
}

/* Below 520 the phone's own bottom furniture is in play, so it tucks tighter
   and sits at 44 - the touch floor, not a new size on the scale. */
@media (max-width:520px){
  .to-top{right:var(--s4);bottom:var(--s4);width:44px;height:44px}
}

/* Only the fade is suppressed. The button's own motion is base.css's to answer
   for and it already handles this query. */
@media (prefers-reduced-motion:reduce){
  .to-top{transition:opacity 1ms linear,visibility 0s linear 1ms}
}
