/* ============================================================
   LUMEN ,  MOBILE TOP BAR
   ------------------------------------------------------------
   A separate system for phones. The desktop bar is one row, and
   its width decides how many of the open tool's buttons stay on
   screen. A phone cannot do that in 390 px, so the phone gets its
   own shape:

     row 1   chrome   back · title · timer · athena · settings ·
                      connection · more
     row 2   strip    the open view's own controls, icon only, one
                      line, scrollable

   Two consequences that the desktop rules get wrong:

     · The strip is measured against the leftover in the chrome
       row, so on a phone it kept four buttons and parked the
       rest. The strip has a line of its own; its budget is that
       line (see ctxBudget in app.js).

     · The overflow menu is a floating panel anchored to a
       button. On a phone it is a sheet off the bottom edge,
       full width, above the home indicator.

   Loaded last, and every rule in it is inside the phone media
   query, so the desktop row is not restyled by any of it.
   ============================================================ */

@media (max-width: 820px) {

  /* ---------- The bar's own measurements ---------- */

  body.m-topbar-on {
    --m-bar-h: 52px;
    --m-strip-h: 46px;
    /* What the shell has to clear. One number, read by the nav,
       the views and the sheet alike. */
    --nav-h: calc(var(--m-bar-h) + var(--m-strip-h) + var(--safe-t, 0px));
  }

  body.m-topbar-on .top-nav {
    height: var(--nav-h) !important;
    display: flex;
    flex-direction: column;
    /* The whiteboard is given a wrapping bar on a desktop, so that its
       forty controls can have a second line. On a phone the bar is two
       rows of its own, and a wrapping COLUMN container sends the
       second row off to the side instead of putting it underneath: the
       strip landed at x=334, on top of the chrome's own ellipsis. */
    flex-wrap: nowrap !important;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0;
    padding-left: calc(8px + env(safe-area-inset-left, 0px)) !important;
    padding-right: calc(8px + env(safe-area-inset-right, 0px)) !important;
    padding-bottom: 0 !important;
    overflow: visible;
  }

  /* ---------- Row 1: the chrome ---------- */

  body.m-topbar-on .m-chrome {
    flex: 0 0 var(--m-bar-h);
    height: var(--m-bar-h);
    display: flex;
    align-items: center;
    gap: 4px;
    min-width: 0;
    overflow: hidden;
  }

  /* The wordmark is the desktop's title. The phone's title is the
     name of the view you are in, which is a different thing. */
  body.m-topbar-on .top-nav > .brand,
  body.m-topbar-on .top-nav > .ctx-grip,
  body.m-topbar-on .top-nav > .flex-1 {
    display: none !important;
  }

  body.m-topbar-on .m-back,
  body.m-topbar-on .m-title,
  body.m-topbar-on .m-more {
    -webkit-appearance: none;
    appearance: none;
    background: none;
    border: 0;
    padding: 0;
    color: var(--fg);
    font: inherit;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    height: 40px;
    min-width: 40px;
    border-radius: 10px;
  }
  body.m-topbar-on .m-back { flex: 0 0 40px; }
  body.m-topbar-on .m-back svg { width: 20px; height: 20px; }

  /* The title is the one piece of text in the bar. It says which
     view you are in, which a row of identical squares cannot. */
  body.m-topbar-on .m-title {
    flex: 1 1 auto;
    min-width: 0;
    justify-content: flex-start;
    gap: 6px;
    padding: 0 6px;
    font: 600 15px/1 var(--sans);
    letter-spacing: -0.01em;
    color: var(--fg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  body.m-topbar-on .m-title svg {
    width: 15px; height: 15px; flex: none; opacity: .7;
  }
  body.m-topbar-on .m-title span {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  body.m-topbar-on .m-title:active { background: color-mix(in srgb, var(--fg) 8%, transparent); }

  body.m-topbar-on .m-more { flex: 0 0 40px; }
  body.m-topbar-on .m-more svg { width: 19px; height: 19px; }

  /* The app chrome inside row 1: icons, same size, same rhythm. */
  body.m-topbar-on .m-chrome > .ibtn,
  body.m-topbar-on .m-chrome > .btn.icon {
    width: 40px !important;
    height: 40px !important;
    min-width: 40px !important;
    min-height: 40px !important;
    border-radius: 10px !important;
    padding: 0 !important;
    justify-content: center !important;
  }
  body.m-topbar-on .m-chrome > .ibtn svg,
  body.m-topbar-on .m-chrome > .btn.icon svg { width: 18px !important; height: 18px !important; }

  /* The connection badge is a fixed dot on the desktop, pinned to the
     corner of the window. In the row it has to be in the flow or it
     floats over the first control. */
  body.m-topbar-on .m-chrome > .net-badge {
    position: static !important;
    width: 22px !important;
    height: 22px !important;
    min-width: 22px !important;
    padding: 0 !important;
    border: 0 !important;
    background: none !important;
    box-shadow: none !important;
  }
  body.m-topbar-on .m-chrome > .net-badge .net-text { display: none !important; }
  body.m-topbar-on .m-chrome > .net-badge .net-dot {
    width: 8px !important; height: 8px !important; margin: 0 !important;
  }

  /* The focus timer is off on a phone.

     It is a ring, a clock and a settings button - three things the
     row does not have, and a timer you did not start is the first
     thing that should not be in your face. It is still one tap away
     in the More sheet, which switches it on; the class on the body
     is what brings the ring back into the row. */
  body.m-topbar-on .m-chrome > .pomo { display: none !important; }
  body.m-topbar-on.m-pomo-on .m-chrome > .pomo { display: flex !important; }
  body.m-topbar-on .m-chrome > .pomo { gap: 4px !important; flex: 0 0 auto; }
  body.m-topbar-on .m-chrome > .pomo .pomo-btn { width: 28px !important; height: 28px !important; }
  body.m-topbar-on .m-chrome > .pomo .pomo-btn svg.ring { width: 28px !important; height: 28px !important; }
  body.m-topbar-on .m-chrome > .pomo .pomo-ic svg { width: 11px !important; height: 11px !important; }
  body.m-topbar-on .m-chrome > .pomo .pomo-meta b { font-size: 12px !important; }
  body.m-topbar-on .m-chrome > .pomo .pomo-meta .lbl { display: none !important; }
  body.m-topbar-on .m-chrome > #pomoCfgBtn { display: none !important; }

  /* Athena keeps her own mark; she is a taskbar button, not a
     toolbar control. */
  body.m-topbar-on .m-chrome > .uchat-fab {
    position: static !important;
    width: 40px !important; height: 40px !important;
    min-width: 40px !important; min-height: 40px !important;
    flex: 0 0 40px !important;
    transform: none !important;
  }

  /* The notebook's save state is a dot on a phone. The word "Saved"
     is two more characters the row does not have. */
  body.m-topbar-on .m-chrome > .nb-chip {
    padding: 0 !important; width: 22px !important; min-width: 22px !important;
    height: 22px !important; border: 0 !important; background: none !important;
  }
  body.m-topbar-on .m-chrome > .nb-chip .nb-text { display: none !important; }

  /* These three live in the phone's More sheet instead of the row.

     A command palette is a keyboard instrument, the notebook's state is a
     dot, and the display button is a desktop idea. None of them earns a
     permanent square in a 390 px row; all of them is one tap away in a
     sheet where each one is named.

     The sidebar's own toggle is NOT in this list. It used to be, and the
     rail was then the one part of the workspace a phone could not
     control: the button that shows and hides the left-hand column was
     in a sheet, behind an ellipsis, while the column itself was always
     on screen taking 54 px of it. The button is worth a square of its
     own - it is the one that gives the width back. */
  body.m-topbar-on .top-nav .m-chrome > #cpTrigger,
  body.m-topbar-on .top-nav .m-chrome > #nbSaveChip,
  body.m-topbar-on .top-nav .m-chrome > #timebarBtn {
    display: none !important;
  }
  /* …and it has to out-specify the desktop's own rules, which hide it
     unless the study workspace is on screen. */
  body.m-topbar-on.study-mode .top-nav .m-chrome > #railToggle,
  body.m-topbar-on .top-nav .m-chrome > #railToggle {
    display: flex !important;
    align-items: center;
    justify-content: center;
  }

  /* ---------- Row 2: the feature strip ---------- */

  /* One ellipsis, not three.

     The desktop's own overflow button is a second one in the same row,
     and the strip's own makes a third. On a phone the strip's is the
     one that opens every control of the view, so the desktop's is
     hidden: three dots in one bar is three ways to ask the same
     question and no way to tell them apart. */
  body.m-topbar-on #ctxMoreBtn { display: none !important; }

  /* A strip with nothing in it is a blank line under the bar, so it
     is taken away and the shell closes up under a one-line bar. */
  body.m-topbar-on.m-strip-empty {
    --nav-h: calc(var(--m-bar-h) + var(--safe-t, 0px));
  }
  body.m-topbar-on.m-strip-empty .m-strip { display: none !important; }

  body.m-topbar-on .m-strip {
    flex: 0 0 var(--m-strip-h);
    height: var(--m-strip-h);
    position: relative;
    min-width: 0;
    display: flex;
    align-items: center;
    border-top: 1px solid var(--line2);
    background: var(--surface);
    /* The strip's own line runs the whole width of the screen.

       The bar has eight pixels of padding at its sides so that the
       buttons do not touch the glass, and the strip's top edge was drawn
       inside that padding. So the line stopped short at both ends: the
       bar had an edge across the middle of the screen and two half-edges
       at the sides of it, which in the contrast skin read as a broken
       rule rather than a border.

       The strip now reaches the edges of the screen and keeps the
       padding for its contents, which is what the padding was for. */
    margin-left: calc(-8px - env(safe-area-inset-left, 0px));
    margin-right: calc(-8px - env(safe-area-inset-right, 0px));
    padding-left: calc(8px + env(safe-area-inset-left, 0px));
    padding-right: calc(8px + env(safe-area-inset-right, 0px));
    /* Nothing in the strip may paint outside it.

       A control taller than the line - the quiz's competency slider, a
       select with the browser's own chrome on it - used to draw over the
       bar's bottom edge. That edge is a bright line in the contrast
       skin, so the bar had a line along its left and right ends and a
       gap in the middle where a control had covered it. A control that
       does not fit the line is cut now, not laid over the page. */
    overflow: hidden !important;
  }
  /* The fade at the right edge says there is more of the row to the
     right. It used to be a gradient in the background colour laid over
     the row - and a fade to the background colour does not dim the last
     control, it ERASES it, so the control nearest the ellipsis was half
     gone and looked broken. In the contrast skin, where the surface and
     the ink are at opposite ends, it drew a bright band straight across
     the row and took the icons with it.

     The scrollable rows have their own mask for this (see .m-overflow
     below), which fades the row rather than painting over it. The strip
     does not need a second one, so there is no overlay here now. */
  body.m-topbar-on .m-strip::after { content: none; }
  /* The strip's own ellipsis: every control the open view has, by
     name, in a list you can read. It is outside the contextual row so
     the row's layout pass never counts it, never parks it and never
     moves it - it is always there. */
  body.m-topbar-on .m-all {
    order: 1;
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
    margin: 0 4px 0 auto;
    -webkit-appearance: none;
    appearance: none;
    background: none;
    border: 0;
    padding: 0;
    color: var(--soft);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    cursor: pointer;
    position: relative;
    z-index: 1;
  }
  body.m-topbar-on .m-all svg { width: 19px; height: 19px; }
  body.m-topbar-on .m-all:active { background: color-mix(in srgb, var(--fg) 8%, transparent); }

  body.m-topbar-on #topContextual {
    display: flex !important;
    align-items: center;
    gap: 4px;
    flex: 1 1 auto !important;
    /* The whiteboard is given `order: 99` on this row, which was to
       push its controls to the end of the bar. In the strip that order
       put it AFTER the ellipsis, so the ellipsis ended up on the left
       and the controls on the right. */
    order: 0 !important;
    min-width: 0;
    width: auto;
    max-width: 100%;
    height: 100%;
    padding: 0 8px;
    overflow-x: auto !important;
    overflow-y: hidden !important;
    flex-wrap: nowrap !important;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    background: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
  body.m-topbar-on #topContextual::-webkit-scrollbar { display: none !important; }
  body.m-topbar-on #topContextual > * { flex: 0 0 auto !important; }

  /* Every control in the strip is a square with one picture in it. */
  body.m-topbar-on #topContextual button,
  body.m-topbar-on #topContextual a {
    width: 40px !important;
    height: 40px !important;
    min-width: 40px !important;
    min-height: 40px !important;
    padding: 0 !important;
    gap: 0 !important;
    justify-content: center !important;
    border-radius: 10px !important;
    flex: 0 0 auto !important;
  }
  body.m-topbar-on #topContextual button svg,
  body.m-topbar-on #topContextual a svg { width: 18px !important; height: 18px !important; }
  body.m-topbar-on #topContextual .ctx-label { display: none !important; }

  /* Readouts are values, not labels: a page number and a zoom
     percentage keep their text, at a size that fits a strip. */
  body.m-topbar-on #topContextual .pgnav,
  body.m-topbar-on #topContextual .zgroup {
    display: inline-flex !important;
    align-items: center;
    gap: 2px;
    flex: 0 0 auto !important;
  }
  body.m-topbar-on #topContextual .pgnav input,
  body.m-topbar-on #topContextual #rCount,
  body.m-topbar-on #topContextual #rPct {
    font-size: 11px !important;
    color: var(--soft);
    min-width: 0;
  }
  body.m-topbar-on #topContextual .pgnav input {
    width: 40px !important; height: 30px !important;
    padding: 0 4px !important; text-align: center;
  }

  /* A select stays a select ,  it is the right control for "PNG /
     JPEG / WebP" ,  but it stops being a wide one. */
  body.m-topbar-on #topContextual select,
  body.m-topbar-on #topContextual input[type="text"],
  body.m-topbar-on #topContextual input[type="search"] {
    height: 32px !important;
    min-height: 32px !important;
    font-size: 12px !important;
    padding: 4px 6px !important;
    max-width: 116px !important;
    border-radius: 9px !important;
  }
  body.m-topbar-on #topContextual .seg {
    flex: 0 0 auto !important;
    display: inline-flex !important;
    border-radius: 10px !important;
    overflow: hidden;
  }
  body.m-topbar-on #topContextual .seg button {
    min-height: 34px !important;
    padding: 0 8px !important;
    min-width: 34px !important;
    justify-content: center !important;
  }
  body.m-topbar-on #topContextual .seg button svg { width: 16px !important; height: 16px !important; }
  body.m-topbar-on #topContextual .seg button .ctx-label { display: none !important; }

  /* ---------- Rows that are wider than the phone ---------- */

  /* A row that scrolls sideways, with nothing to say so, looks cut off.
     The fade at the right edge is the sign, and it comes off again when
     the row has been scrolled to its end - so the last control in the
     row is never the one that looks broken. */
  body.m-topbar-on .m-overflow {
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 24px), transparent 100%);
    mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 24px), transparent 100%);
  }
  body.m-topbar-on .m-overflow.m-overflow-end {
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 24px, #000 100%);
    mask-image: linear-gradient(90deg, transparent 0, #000 24px, #000 100%);
  }
  body.m-topbar-on .m-overflow {
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  body.m-topbar-on .m-overflow::-webkit-scrollbar { display: none !important; }

  /* ---------- The whiteboard's own toolbar ---------- */

  /* The whiteboard keeps its toolbar in a row of its own, and two of
     its controls were taking the whole row: the stroke-size slider
     and the colour palette. The slider was as wide as the screen, the
     palette as wide again, and the controls between them - undo, redo,
     the zoom readout - were squeezed down to a character wide, which
     is how "100%" came out as "7 2 %". */
  body.m-topbar-on #wbToolHead .top-actions #wbSize,
  body.m-topbar-on #wbToolHead .top-actions input[type="range"] {
    width: 84px !important;
    flex: 0 0 auto !important;
  }
  body.m-topbar-on #wbToolHead .top-actions #wbColors { flex: 0 0 auto !important; }
  /* The colour circles were the size of a touch target.

     Every button on a phone is given a 44 px box so a finger can find it,
     and a swatch is a button - so the eight circles of the palette were
     44 px each, 350 px of a 374 px row, and every other control in the
     toolbar was pushed off the screen. A circle of colour is not a
     control that needs a finger-sized box around it; it is a picture of
     a colour, and it wants to be the size of the other pictures in the
     row.

     The class is `.swatch` on one build and `.wb-swatch` on the other, so
     the rule that was meant to size them down matched only half of them
     and the circles stayed at the touch size. Both names are covered here
     so neither can drift again.

     Twenty-four is the size of the other pictures in the row, with room
     for the selected colour's ring: that ring is drawn seven pixels out
     from the circle, so a circle of thirty reached thirty-seven and was
     shaved by the edge of the line it sat in. */
  body.m-topbar-on #wbToolHead .top-actions #wbColors .swatch,
  body.m-topbar-on #wbToolHead .top-actions #wbColors .wb-swatch {
    width: 24px !important;
    height: 24px !important;
    min-width: 24px !important;
    min-height: 24px !important;
    padding: 0 !important;
    border-width: 2px !important;
  }
  /* The selected swatch is drawn larger than the others, and a row that
     is exactly as tall as the row of swatches clips the top of it: the
     tick inside the selected colour was cut in half. The row is given
     room for the swatch to be bigger than its box - and the header is
     allowed to show it, because the ring is drawn outside the circle. */
  body.m-topbar-on #wbToolHead,
  body.m-topbar-on #wbToolHead .tool-head {
    overflow: visible !important;
  }
  body.m-topbar-on #wbToolHead .top-actions #wbColors .swatch.active,
  body.m-topbar-on #wbToolHead .top-actions #wbColors .swatch.on,
  body.m-topbar-on #wbToolHead .top-actions #wbColors .wb-swatch.active,
  body.m-topbar-on #wbToolHead .top-actions #wbColors .wb-swatch.is-on { transform: none !important; }
  /* "Add to Library" is a mark on a phone.

     The board's toolbar spells it out in full - the word beside the
     library mark - and on a 390 px row that word is worth more than
     several of the forty controls beside it. The mark says the same
     thing, and the button keeps its title and its label for anyone who
     needs to read it. */
  body.m-topbar-on #wbToolHead .top-actions #wbSaveLib .ctx-label { display: none !important; }
  body.m-topbar-on #wbToolHead .top-actions #wbSaveLib { flex: 0 0 auto !important; }

  /* The tiles have to fit the line.

     Every button on a phone is given a 44 px box, and the board's tiles
     are buttons - so a row that is meant to be 40 px tall held 44 px of
     button, and the row was clipped. Compact showed one row with the top
     and the bottom of every tile shaved off; Medium showed one whole row
     and a slice of the next, because 44 + 6 + 44 is more than the 86 px
     two whole rows are given. Changing the setting from Compact to
     Medium changed nothing a finger could see, because the row was
     already being cut.

     The tiles are drawn at 38 px on a desktop, and 40 is the line height
     that was measured from them, so that is what they are here. */
  body.m-topbar-on #wbToolHead .top-actions .ibtn {
    width: 38px !important;
    height: 38px !important;
    min-width: 38px !important;
    min-height: 38px !important;
    padding: 0 !important;
    border-radius: 8px !important;
  }
  body.m-topbar-on #wbToolHead .top-actions .ibtn svg,
  body.m-topbar-on #wbToolHead .top-actions .ibtn i[data-lucide] {
    width: 18px !important;
    height: 18px !important;
  }
  /* The slider is a control, not a field: it kept the form's padding and
     came out with its track inset by twelve pixels a side. */
  body.m-topbar-on #wbToolHead .top-actions input[type="range"] {
    padding: 0 !important;
    font-size: inherit !important;
    border-radius: 0 !important;
  }

  /* More of the whiteboard's toolbar at once. Its row is one line that
     scrolls sideways, so most of its forty controls are off the screen
     with nothing to say so - the user has to know they are there. Two
     lines show twice as many, and the space they take is space the
     floating dock was covering anyway. */
  body.m-topbar-on #wbToolHead .top-actions {
    flex-wrap: wrap !important;
    /* The height is the desktop's own calculation, so the Compact /
       Medium setting means what it says: a whole number of lines, at the
       height the tiles are drawn at, with the gap between them and
       nothing left over. Compact is one line of 40; Medium is two lines
       of 40 with 6 between them.

       The vertical padding the row used to carry is gone, because it was
       counted against this height - 8 px of padding in a box sized for
       86 px of rows left 78 px for rows that need 86, and the second
       line was always cut short. The room the selected colour needs is
       given to it inside its own circle instead, where no clipping can
       reach it. */
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    max-height: calc(var(--ctx-rows, 2) * var(--wb-line, 40px) + (var(--ctx-rows, 2) - 1) * 6px);
    overflow-x: auto !important;
    overflow-y: auto !important;
    align-content: flex-start;
  }
  body.m-topbar-on #wbToolHead .top-actions #wbColors .swatch.on {
    outline: none !important;
    box-shadow: 0 0 0 2px var(--accent) !important;
  }
  body.m-topbar-on #wbToolHead .top-actions > * { flex: 0 0 auto !important; }
  body.m-topbar-on #wbToolHead .top-actions .mini {
    flex: 0 0 auto !important;
    white-space: nowrap !important;
  }
  body.m-topbar-on #wbToolHead .top-actions .vsep { flex: 0 0 auto !important; }
  /* A control with a word in it must not have the word broken across
     lines to fit. */
  body.m-topbar-on #wbToolHead .top-actions .lsw-dock-b span,
  body.m-topbar-on #wbToolHead .top-actions button { white-space: nowrap !important; }

  /* ---------- The whiteboard's settings panel ---------- */

  /* The panel is a dialog on a desktop and a sheet on a phone, and it was
     neither: it kept the desktop's inset, so it stopped short of the top
     and the bottom of the screen and left a band of the board showing
     under it.

     On a phone it is the whole screen. Its rows are two across, because a
     name like "Load a saved board" needs the room: three across - which
     is what the touch-sized boxes gave - left each name a column a few
     pixels wide, and a name in a column that narrow is broken between its
     letters rather than wrapped between its words. That is where "Expor /
     t PNG" and "Temp / lates" came from. */
  body.m-topbar-on .wb-settings {
    inset: 0 !important;
    width: auto !important;
    max-width: none !important;
    height: auto !important;
    margin: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
  }
  body.m-topbar-on .wbs-head { padding: 14px 16px !important; }
  body.m-topbar-on .wbs-head h2 { font-size: 17px !important; }
  body.m-topbar-on .wbs-body { padding: 4px 16px 24px !important; }
  body.m-topbar-on .wbs-sec { padding: 14px 0 !important; }
  body.m-topbar-on .wbs-note { font-size: 12.5px !important; }
  body.m-topbar-on .wbs-grid { gap: 8px !important; }
  body.m-topbar-on .wbs-check {
    flex: 1 1 132px;
    min-width: 0;
    min-height: 42px;
    gap: 8px !important;
    font-size: 12.5px !important;
    padding: 8px 10px !important;
    /* A name is a name. It must not be broken between its letters to fit
       a box, and it must not be shrunk to nothing either. */
    overflow-wrap: normal !important;
    word-break: keep-all !important;
    text-align: left !important;
  }
  body.m-topbar-on .wbs-check input[type="checkbox"],
  body.m-topbar-on .wbs-check input[type="radio"] {
    flex: none !important;
    width: 18px !important;
    height: 18px !important;
    min-width: 18px !important;
    min-height: 18px !important;
    padding: 0 !important;
    margin: 0 !important;
  }
  body.m-topbar-on .wbs-ic,
  body.m-topbar-on .wbs-ic svg { width: 17px !important; height: 17px !important; }
  body.m-topbar-on .wbs-chip { min-height: 38px !important; }
  body.m-topbar-on .wbs-foot { padding: 12px 16px !important; }
  body.m-topbar-on .wbs-foot .btn { flex: 1 1 auto !important; }

  /* ---------- The study workspace's own rows ---------- */

  /* The Reader's leftover row was a bar.

     Its controls have been moved into the strip, and what was left behind
     was the file's name in a row with a rule under it: a bar across the
     top of the page, with the document pushed down and cut off underneath
     it. In the contrast skin, where every rule is a bright line, that bar
     was the brightest thing on the screen and it drew a second edge under
     the bar's own.

     The name stays - it is worth knowing which document is open - but it
     stops being a bar: no rule under it, no panel behind it, and a line's
     worth of height instead of a row's. */
  body.m-topbar-on #view-study .study-view[data-view="reader"] > .vbar {
    min-height: 0 !important;
    max-height: none !important;
    padding: 3px 12px !important;
    border-bottom: 0 !important;
    background: none !important;
    flex-wrap: nowrap !important;
    overflow: hidden !important;
  }
  body.m-topbar-on #view-study .study-view[data-view="reader"] > .vbar .rname {
    border-left: 0 !important;
    padding-left: 0 !important;
  }

  /* ---------- The study workspace's own floating dock ---------- */

  /* The dock is a row of controls over the bottom of the page, and the
     last of them is Hide - the control that puts the row away.

     On a phone every button in it was given the 44 px touch box, so the
     row was forty pixels wider than the screen. It scrolled, and the
     Hide control was the last thing in a scrolling row: off the right
     edge, with the finger asked to find it. So the switcher could not
     be put away even though it was right there.

     The boxes go back to the size they are drawn at and the row fits, so
     every control in it - Hide included - is under the thumb without
     being hunted for.

     The three layout buttons go as well: tiling panels side by side and
     staggering them are things a wide window does, and on a phone they
     are three buttons' worth of room the Hide control needed. */
  body.m-topbar-on .lsw-dock {
    left: 8px !important;
    right: 8px !important;
    transform: none !important;
    flex-wrap: nowrap !important;
    justify-content: flex-start !important;
    max-width: none !important;
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding-bottom: calc(5px + env(safe-area-inset-bottom, 0px));
  }
  body.m-topbar-on .lsw-dock::-webkit-scrollbar { display: none !important; }
  body.m-topbar-on .lsw-dock-b {
    flex: 0 0 auto !important;
    width: 32px !important;
    min-width: 32px !important;
    height: 32px !important;
    min-height: 32px !important;
    padding: 0 !important;
  }
  body.m-topbar-on .lsw-dock-b svg,
  body.m-topbar-on .lsw-dock-b i[data-lucide] { width: 17px !important; height: 17px !important; }
  body.m-topbar-on .lsw-dock-tools { flex: 0 0 auto !important; }
  body.m-topbar-on .lsw-dock-tools .lsw-dock-b[aria-label^="Tile"],
  body.m-topbar-on .lsw-dock-tools .lsw-dock-b[aria-label^="Split into rows"],
  body.m-topbar-on .lsw-dock-tools .lsw-dock-b[aria-label^="Stagger"] { display: none !important; }
  /* The Hide control used to be pinned to the end of the row with an
     opaque patch behind it, so that it stayed under the thumb while the
     row scrolled. The patch was the problem: it was the colour of the
     panel laid over the bar, so it painted out the bar's own outline
     where it sat - in the contrast skin that was a bright band across
     the bottom of the screen - and it covered the edge of the control
     beside it. The row fits now, so the control is simply there and
     there is nothing to paint over anything. */
  body.m-topbar-on .lsw-dock-tools .lsw-dock-b:last-child {
    position: static;
    background: none;
    box-shadow: none;
  }
  /* The dock floats over the page, so the page has to be taller than the
     page it floats over. */
  body.m-topbar-on #view-study .rbody,
  body.m-topbar-on #view-study .study-view { padding-bottom: 64px !important; }

  /* ---------- Sheets ---------- */

  /* Athena is a floating window on a desktop: a panel that sits beside
     the work and can be dragged and resized. On a phone there is no
     beside to float in, and a 350 px window in the middle of the
     screen covers the page it is supposed to be about. It becomes a
     sheet of its own, under the bar and over everything else. */
  body.m-topbar-on #uchat {
    position: fixed !important;
    left: 0 !important;
    right: 0 !important;
    top: var(--nav-h) !important;
    bottom: 0 !important;
    width: 100% !important;
    max-width: 100% !important;
    height: auto !important;
    max-height: none !important;
    border-radius: 0 !important;
    z-index: 200 !important;
  }
  body.m-topbar-on #uchat .uchat-resize { display: none !important; }
  /* The prompt is a long sentence and the box is a third of the screen
     wide, so the placeholder wraps to two lines - and a one-line box
     clips the second one. */
  body.m-topbar-on #uchat .uchat-in { min-height: 58px !important; }

  /* The overflow menu is a sheet off the bottom edge. The panel is
     positioned by the script that opens it, so these have to win
     against an inline position. */
  body.m-topbar-on .pop.ctx-menu {
    position: fixed !important;
    left: 0 !important;
    right: 0 !important;
    top: auto !important;
    bottom: 0 !important;
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
    max-height: 72dvh !important;
    overflow-y: auto !important;
    overscroll-behavior: contain;
    padding: 10px 10px calc(14px + env(safe-area-inset-bottom, 0px)) !important;
    gap: 4px !important;
    border-radius: 18px 18px 0 0 !important;
    animation: m-sheet-in 0.18s ease-out;
  }
  body.m-topbar-on .pop.ctx-menu > * {
    width: 100% !important;
    min-height: 46px !important;
    justify-content: flex-start !important;
  }
  body.m-topbar-on .pop.ctx-menu .ctx-adopted,
  body.m-topbar-on .pop.ctx-menu .ibtn {
    width: 100% !important;
    height: auto !important;
    min-width: 0 !important;
    min-height: 46px !important;
    padding: 8px 12px !important;
    gap: 12px !important;
    justify-content: flex-start !important;
    border-radius: 12px !important;
    font-size: 14px !important;
  }
  body.m-topbar-on .pop.ctx-menu .ctx-menu-label {
    font-size: 14px !important;
    white-space: normal !important;
  }

  /* The phone's own sheet: the tools list and the app's overflow.
     It is above the cat and the loader - a sheet with a cat walking
     across it is a sheet you are reading through a parade. */
  body.m-topbar-on .m-sheet {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 10010;
    max-height: 76dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--surface);
    color: var(--fg);
    border-top: 1px solid var(--line2);
    border-radius: 18px 18px 0 0;
    box-shadow: 0 -12px 40px -12px rgba(0, 0, 0, 0.6);
    padding: 6px 0 calc(14px + env(safe-area-inset-bottom, 0px));
    animation: m-sheet-in 0.18s ease-out;
  }
  body.m-topbar-on .m-sheet-grip {
    width: 38px; height: 4px; border-radius: 99px;
    background: var(--line2);
    margin: 6px auto 8px;
  }
  body.m-topbar-on .m-sheet-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px; padding: 2px 16px 8px;
    font: 700 11px/1 var(--mono);
    letter-spacing: .14em; text-transform: uppercase;
    color: var(--soft);
  }
  body.m-topbar-on .m-sheet-sec {
    padding: 10px 16px 4px;
    font: 700 10px/1 var(--mono);
    letter-spacing: .14em; text-transform: uppercase;
    color: var(--soft);
    opacity: .8;
  }
  body.m-topbar-on .m-sheet-row {
    display: flex; align-items: center; gap: 12px;
    width: 100%;
    min-height: 48px;
    padding: 8px 16px;
    background: none; border: 0;
    color: var(--fg);
    font: 500 15px/1.2 var(--sans);
    text-align: left;
    cursor: pointer;
  }
  body.m-topbar-on .m-sheet-row:active { background: color-mix(in srgb, var(--fg) 7%, transparent); }
  body.m-topbar-on .m-sheet-row .m-sheet-ico {
    width: 30px; height: 30px; flex: none;
    display: grid; place-items: center;
    border-radius: 9px;
    background: var(--surface-2);
    color: var(--fg);
  }
  body.m-topbar-on .m-sheet-row .m-sheet-ico svg { width: 16px; height: 16px; }
  body.m-topbar-on .m-sheet-row .m-sheet-txt { min-width: 0; }
  body.m-topbar-on .m-sheet-row .m-sheet-txt small {
    display: block; font-size: 11.5px; color: var(--soft); margin-top: 2px;
  }
  body.m-topbar-on .m-sheet-row.is-on .m-sheet-ico { color: var(--accent); }

  /* ---------- What the bar replaces ---------- */

  /* Three headers for one place is two too many.

     The phone's bar already says which view you are in, so the study
     workspace's own two header rows are left with the parts that
     are not in the bar: the notebook you are in, and the buttons that
     did not fit. The repeated titles - the breadcrumb's current
     segment and the row's own heading - go, because the bar is
     standing right above them saying the same thing. */
  body.m-topbar-on #view-study .bc-seg.bc-current,
  body.m-topbar-on #view-study .bc-sep + .bc-seg.bc-current,
  body.m-topbar-on #view-study .study-view .vbar .vtitle,
  body.m-topbar-on #view-study .ls-crumbs {
    display: none !important;
  }
  body.m-topbar-on #view-study .breadcrumbs { padding: 4px 12px !important; }

  /* The phone now has a bar of its own, so the notice that says the
     app is built for a desktop has nothing left to say. */
  body.m-topbar-on .mobile-note { display: none !important; }

  /* The shell has to clear a bar that is two rows tall. */
  body.m-topbar-on .view {
    padding-top: calc(var(--nav-h) + var(--banner-h, 0px)) !important;
  }

  /* Nothing may be wider than the screen. A guide column that is
     396 px on a 390 px phone scrolls the whole page sideways. */
  body.m-topbar-on .guide-wrap { max-width: 100% !important; width: 100% !important; }

  /* The chrome sheet is opened by the phone's own module, so it is
     dismissed the same way. */
  body.m-topbar-on .m-sheet-scrim {
    position: fixed; inset: 0; z-index: 10009;
    background: rgba(0, 0, 0, 0.45);
    animation: m-fade-in 0.16s ease-out;
  }
}

@keyframes m-sheet-in {
  from { transform: translateY(14px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}
@keyframes m-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .m-sheet, .m-sheet-scrim, .pop.ctx-menu { animation: none !important; }
}
