/* Either condition switches the whole bar over to the hamburger/panel layout: a
   narrow window (a resized desktop browser, mouse and all) still gets it as
   before, and now a touch device gets it too however wide its screen is — a
   tablet is not a phone, but it is not a mouse either. A comma between media
   queries is an OR, not an AND */
@media only screen and (max-width: 600px), only screen and (hover: none) {
  /* The bar's surface is a layer of its own instead of a background on the
     header, so the panel can hide behind it. A background on the header itself
     would not do: a child always paints on top of its parent's background */
  header::before {
    content: "";
    position: absolute;
    inset: 0;
    background-color: var(--background-color-navbar-and-menu-button);
    z-index: 1;
  }

  .nav-toggle {
    display: inline-flex;
    position: relative;
    z-index: 2;
  }

  /* The navbar becomes a panel that lies over the page instead of pushing
     <main> down. top: 100% puts it directly below the header, which is the
     containing block because main-menu.css makes it sticky.
     Closed it is not clipped away but parked one panel height higher, behind
     the bar. That way the three buttons arrive and leave as one block, instead
     of appearing one after another as a growing window uncovers them */
  .navbar {
    display: flex;
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 0;
    flex-direction: column;
    align-items: stretch;
    /* Only here, not on the shared .navbar rule: the desktop bar is meant to
       run the full width of the window. This one is a panel hanging off the
       header, and on a wide tablet — which now gets this layout on hover:none
       alone, at any width — a full-width panel of stacked buttons would be a
       lot of empty space for very little menu */
    max-width: var(--menu-max-width);
    /* The same rounding the menu buttons and submenus already use, so the panel
       reads as one of the menu's own surfaces rather than a plain slab, with an
       outline to match. Only here and not on the shared .navbar rule: the
       desktop bar spans the whole window, where a border would just draw lines
       along the window's own edges */
    border-radius: var(--border-radius);
    border: 1px solid var(--border-color-navbar);
    /* Never taller than the room under the header, and scrollable once it would
       be. --bar-height, not --nav-toggle-size: the header's real height is the
       bar's height, not the icon's own size, and the two only used to agree by
       accident, back when the bar's height was wrongly tied to the icon's size.
       svh and not dvh: svh is the height with the browser's own bars in view,
       so the menu keeps fitting when one of them slides back in. The vh line
       above it is the fallback for browsers that do not know the unit */
    max-height: calc(100vh - var(--bar-height, 24px));
    max-height: calc(100svh - var(--bar-height, 24px));
    max-height: var(--panel-height, calc(100svh - var(--bar-height, 24px)));
    overflow-y: auto;
    /* Only the vertical axis. contain on both would also swallow sideways
       gestures, and those are what you need to reach the rest of a zoomed-in
       page. Vertically it still stops the page behind from scrolling along */
    overscroll-behavior-y: contain;
    transform: translateY(-100%);
    visibility: hidden;
    /* Same reasoning as on .dropdown, and it matters more here: closing the
       panel on top of an open submenu waits a whole --navbar-delay before the
       sliding even starts, and then slides for another --menu-transition. That
       is over a second in which the buttons sit perfectly still, fully visible,
       and would happily take a tap on a menu that is already closing */
    pointer-events: none;
    /* --navbar-delay is --menu-transition when a submenu still has to collapse
       first and 0s otherwise, so closing never waits for an animation that is
       not running. visibility follows only once the sliding is done, and keeps
       the parked buttons out of reach of the Tab key in the meantime */
    transition:
      transform var(--menu-transition) ease var(--navbar-delay, 0s),
      visibility 0s calc(var(--menu-transition) + var(--navbar-delay, 0s));
  }

  header.nav-open .navbar {
    transform: none;
    visibility: visible;
    pointer-events: auto;
    transition:
      transform var(--menu-transition) ease,
      visibility 0s;
  }

  /* Button above its own submenu. align-items defaults to stretch, so both
     fill the width and the whole row is tappable */
  .navbar > div {
    flex-direction: column;
  }

  /* Nothing in the panel is allowed to be squeezed: if it does not fit, the
     panel scrolls. Spelled out because .menu-btn has overflow: hidden, which
     sets its automatic minimum size to zero and would let it collapse */
  .navbar > div,
  .navbar > div > .menu-btn {
    flex-shrink: 0;
  }

  /* Same vertical rhythm as a dropdown item's own padding, so File/Edit/Help
     do not sit more cramped than the rows they open. Only top/bottom: the
     horizontal padding is desktop's optical alignment with the dropdown text
     below it, and stays as it is */
  .navbar > div > .menu-btn {
    padding-top: var(--item-padding-y);
    padding-bottom: var(--item-padding-y);
    /* Square here, unlike the desktop bar where each button is its own separate
       shape. Stacked full-width in a panel they read as rows of one surface,
       and rounding every one of them would fight that. The panel's own rounded
       corners still win at the very top and bottom: it scrolls, and a scrolling
       box clips whatever is inside it to its own rounding */
    border-radius: 0;
  }

  /* Accordion: the submenu sits in the flow and pushes the rest of the list
     down, rather than hanging over it. The clipping, border and height cap all
     come straight from main-menu.css; only the position and the two rules below
     are different here */
  .dropdown {
    position: static;
    /* The 1001 from main-menu.css is meant for the desktop menu hanging over the
       page. Here it would paint the submenu over the arrow below, because a flex
       item takes its z-index even while it is not positioned */
    z-index: auto;
    /* Square, like the menu buttons above it: stacked full-width inside the
       panel these are rows of one surface, not separate shapes. The panel's own
       rounded corners still hold at the very top and bottom, because .navbar
       scrolls and a scrolling box clips its contents to its own rounding */
    border-radius: 0;
  }

  .dropdown.is-open {
    /* Top and bottom only: the sides would run parallel to the panel's own
       border a pixel away, doubling it up along the full height of the submenu.
       These two are what separate the submenu from the buttons above and below
       it, and those are the only edges that need marking */
    border-left: none;
    border-right: none;
    /* svh instead of main-menu.css's dvh: svh is the height with the browser's
       own bars in view. dvh would let the cap grow the instant the address bar
       slides away, and the scrollbar would flicker on and off as it does */
    max-height: min(var(--dropdown-content-height), 60vh);
    max-height: min(var(--dropdown-content-height), 60svh);
    /* No overscroll-behavior here on purpose: at either end of the submenu the
       swipe is meant to carry on into the panel around it. The panel does have
       it, so the chain stops there and never reaches the page behind */
    overscroll-behavior: auto;
  }
}

/* Without a pointer a scrollbar is not a control but a hint: you swipe, you do
   not drag it. Hiding it there costs nothing. Where there is a mouse it stays,
   because there it is the only way to scroll without a wheel.
   The second rule is for Safari, which supported the first one only much later.
   hover: none alone is enough here, with no width check needed: the accordion
   layout above now switches on hover:none too, so lacking a hover-capable
   pointer already guarantees the accordion row this button's positioning
   depends on. That was not true before that layout was width-only — a touch
   device at a desktop width used to get this button with nothing to position
   it against, planting it up near the menu-btn instead of under the dropdown */
@media (hover: none) {
  .navbar,
  .dropdown.is-open {
    scrollbar-width: none;
  }

  .navbar::-webkit-scrollbar,
  .dropdown.is-open::-webkit-scrollbar {
    display: none;
  }

  /* One size for the scroll button: its height, its width, and the centring of
     the arrow inside it all come from here. In em, so it follows the font.
     Set on .navbar rather than .navbar > div, so both a submenu's own button
     and the panel's own button (a direct child of .navbar, see further down)
     can read the same two values */
  .navbar {
    --scroll-strip: 1.6em;
    /* Half the width/height of the arrow triangle below, so the three border
       values that draw it and the centring math above it stay in step */
    --scroll-arrow: 0.35em;
  }

  /* Shrinks the 60% cap from the outer media query by the height of the
     panel's own scroll button, so a submenu sitting right at that limit still
     leaves room below it for the panel button to overlay without ever landing
     on the exact same line as the submenu's own scroll button. Only touch mode
     has a panel button to make room for, which is why this narrows the cap
     here rather than in the cap's own rule above */
  .dropdown.is-open {
    max-height: min(var(--dropdown-content-height), calc(60vh - var(--scroll-strip)));
    max-height: min(var(--dropdown-content-height), calc(60svh - var(--scroll-strip)));
  }

  /* How it looks; whether it is shown at all is decided in the rule below.
     A pixel clear of the edges, so it stays inside the border of the menu */
  .scroll-btn {
    position: absolute;
    bottom: 1px;
    right: 1px;
    /* Twice as wide as it is high, from the same variable, so one number keeps
       the proportion whatever the font size does */
    width: calc(var(--scroll-strip) * 2);
    height: var(--scroll-strip);
    /* Without this, real touch hardware can hand the whole gesture to .navbar
       instead of this button: the button sits inside .navbar, which is itself
       the scrolling element, so any touch that starts here is also a candidate
       for panning that ancestor. manipulation (tried first) only rules out
       double-tap-zoom and the tap-versus-gesture delay, but still lets a drag
       that starts here scroll the navbar underneath — none rules out every
       native gesture starting from this button, dragging included, so the
       whole interaction stays with our own pointer handlers regardless of how
       still or how much the finger moves. RDM's simulated touch never shows
       either problem, since it is just mouse events underneath, with none of a
       real OS's gesture recognition to compete with */
    touch-action: none;
    /* Fully transparent by default: while it is only sitting there to catch a
       stray tap (is-pressed, is-held) and has no arrow to show for itself, it
       should not read as a button at all */
    background-color: transparent;
    border: 1px solid transparent;
    border-radius: var(--border-radius);
    cursor: pointer;
    /* Otherwise a double tap selects the hidden label inside it: nothing visible
       to see, just a stray highlight where the button sits */
    -webkit-user-select: none;
    user-select: none;
  }

  /* The panel's own button, for when File/Edit/Help (and whatever submenu is
     open between them) do not all fit either. A direct child of .navbar, one
     level up from a submenu's button, which sits inside .navbar > div instead.
     Sticky rather than absolute: .navbar is the thing scrolling here, and an
     absolutely positioned child of the element that is itself scrolling is
     placed against the full scrollable content, not the visible window onto
     it — it would sit at the true bottom, past Help, and scroll out of view
     with everything else. Sticky keeps it pinned to the bottom of whatever is
     currently in view instead, the way a sticky footer works in a long list.
     flex-end because .navbar stretches its children full width by default;
     the explicit width from the shared rule above already keeps it narrow, this
     only stops that width from being stretched back out again.
     flex-shrink: 0 for the same reason .navbar > div needs it above: once the
     content genuinely overflows max-height, a default-shrinkable flex item gets
     squeezed to fit instead of being left to overflow and scroll. The arrow is
     drawn by an absolutely positioned ::after sized in its own em unit, so a
     squeezed button still shows a full-size arrow — just no longer where the
     button's real, shrunk hit target is, so a tap on it landed on whatever was
     behind it instead.
     margin-top pulls it back up over its own height, so showing the button does
     not add a row's worth of extra scrollable space at the end of the panel —
     it overlays whatever is currently the last visible row instead. That row
     can be an open submenu, and the button sitting over part of it, scrolling
     it further, or it folding away as a result are all fine: nothing here is
     built to protect an open submenu from this button on purpose */
  .navbar > .scroll-btn {
    position: sticky;
    align-self: flex-end;
    flex-shrink: 0;
    margin-top: calc(-1 * var(--scroll-strip));
  }

  /* Shown while there is something below. Also while a pointer is still on it
     (is-pressed) or shortly after it was (is-held): pulling the button out from
     under a finger, or straight after it lifts, would put the very next tap
     onto the menu item behind it instead */
  .navbar > div.has-more .scroll-btn,
  .navbar.has-more > .scroll-btn,
  .scroll-btn.is-pressed,
  .scroll-btn.is-held {
    display: block;
  }

  /* The look, kept apart from whether the button is shown at all. Only with an
     arrow (has-more) does it read as one of the menu's own rows, the same look
     a dropdown item gets under the pointer. More specific than the transparent
     default above, so it wins only when has-more is actually present */
  .navbar > div.has-more .scroll-btn,
  .navbar.has-more > .scroll-btn {
    background-color: var(--background-color-dropdown-item-hover);
    border-color: var(--border-color-dropdown-item-hover);
  }

  /* The arrow, as a shape on the button rather than as its text: this way it
     scales with the font and takes its colour from your own variables */
  .scroll-btn::after {
    content: "";
    position: absolute;
    bottom: calc((var(--scroll-strip) - var(--scroll-arrow)) / 2);
    left: 50%;
    width: 0;
    height: 0;
    border-left: var(--scroll-arrow) solid transparent;
    border-right: var(--scroll-arrow) solid transparent;
    border-top: var(--scroll-arrow) solid var(--color-active-item);
    transform: translateX(-50%);
    opacity: 0;
    transition: opacity 200ms ease;
  }

  .navbar > div.has-more .scroll-btn::after,
  .navbar.has-more > .scroll-btn::after {
    opacity: 1;
  }
}
