/*
 * Copied from nanatam at 36f976d, unchanged. The comments below were written
 * there and tell that history; "the panel" and "Mission Control" are nanatam's.
 */
/*
 * The writing toolbar's looks, shipped next to the script that builds it.
 *
 * ## Why this file exists at all
 *
 * "På admin-panelen är det också för mycket utrymme nedåt och väldigt fult
 *  med ikonerna."
 *
 * The script was shared and the stylesheet was not. `rich-text.js` moved to
 * `@shell/core/public` so the customer's own panel could have the same writing
 * tools as mail.bastion.nu, and every `.rt-*` rule stayed behind in Mission
 * Control's `mail.css`. On the panel that meant: a `contenteditable` with no
 * height at all - so the message box was simply not on the screen - default
 * browser buttons for every icon, and the whole of the pane below the row left
 * empty because the element that was supposed to grow into it could not.
 *
 * A shared component that only looks right on the host it was written for is
 * not shared. Script and stylesheet move together from here on.
 *
 * ## The six names
 *
 * Each host has its own palette under its own names - Mission Control's mail
 * client says `--ink` and `--line`, the customer's panel says `--a-ink` and
 * `--a-line`, and neither is going to change to suit the other. So this file
 * asks for `--rt-*` and each host maps its own six in one small block. The
 * fallbacks are what a third host would get with no mapping at all: readable,
 * unremarkable, and never invisible.
 *
 *   --rt-ink      the text being written
 *   --rt-muted    labels, placeholders, an unpressed icon
 *   --rt-line     hairlines
 *   --rt-accent   focus rings and links
 *   --rt-hover    the wash under a hovered or pressed control
 *   --rt-sunk     the toolbar's own ground, a shade off the page
 *
 * `--rt-sunk` MUST BE OPAQUE, and that stopped being a matter of taste when
 * the toolbar became `position: sticky` (see the block below). The fallback
 * here was `rgba(127, 127, 127, .05)` and Mission Control mapped it onto an
 * undefined `--sunk`, so it fell through to that same translucent grey - which
 * is invisible until something scrolls underneath it, and then it is the
 * message's own text sliding through the buttons. A host mapping a see-through
 * colour onto this name is a host whose toolbar looks broken while scrolling
 * and perfect in a screenshot.
 */

/* .rt-slot and .rt-bar-slot are empty divs in the template: one marks where the
   writing surface goes, the other where the toolbar goes. `display: contents`
   on both, so neither is a box that could collapse a margin or bound a width -
   they are places in the flow and nothing more. They carry a rule at all so
   that the stylesheet-and-markup test has something to find. */
.rt-slot { display: contents; }
.rt-bar-slot { display: contents; }

/* Said once, and it has to be said: `hidden` works through the user-agent
   rule `[hidden] { display: none }`, which ANY author `display` beats. The
   emoji sheet and the link row learned this the hard way - both stood
   permanently open, filling a third of the compose pane, because the rules
   further down set `display: flex`. */
.rt-bar[hidden] { display: none; }
.rt-sheet[hidden], .rt-link[hidden] { display: none; }
/* A <template>, which renders nothing by definition. Named here so it cannot
   be given a box by some later `div` rule. */
.rt-seed { display: none; }

/* ---------------------------------------------------------------------------
   The two controls that live in the message's own button row

   The formatting toggle, and the buttons that put something INTO the message -
   a link, a face, a signature. Gmail draws that line and it is the right one:
   these are not formatting, they are things you add, so they must not be
   behind a toggle somebody has to know to press first.

   They stand beside the paperclip and are drawn to match it: 2rem square,
   muted until touched. They were smaller and fainter than their neighbours
   once and read as stray letters rather than controls.
   --------------------------------------------------------------------------- */
.rt-toggle,
.rt-insert {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--rt-muted, #6b7280);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}
.rt-toggle:hover,
.rt-insert:hover {
  background: var(--rt-hover, rgba(127, 127, 127, .12));
  color: var(--rt-ink, #111827);
}
.rt-toggle:focus-visible,
.rt-insert:focus-visible {
  outline: 2px solid var(--rt-accent, #2563eb);
  outline-offset: 1px;
}
/* Pressed reads as pressed: the toolbar the toggle opens is a state, not a
   one-off. */
.rt-toggle[aria-expanded="true"] {
  background: var(--rt-hover, rgba(127, 127, 127, .18));
  color: var(--rt-ink, #111827);
}
/* The signature button is the one insert that can be OFF, so it needs a
   pressed state the others do not: the whole question it answers is whether a
   name goes at the bottom of this one message. */
.rt-insert[aria-pressed="true"] {
  background: var(--rt-hover, rgba(127, 127, 127, .18));
  color: var(--rt-ink, #111827);
}
.rt-insert[aria-pressed="false"] { opacity: .55; }

/* ---------------------------------------------------------------------------
   The formatting toolbar itself, behind the toggle
   --------------------------------------------------------------------------- */
/*
 * IT SITS ABOVE THE TEXT, AND IT IS NOT ANCHORED TO THE BOTTOM OF ANYTHING.
 *
 * ## The two complaints, in order
 *
 * "På mobil-versionen för mail när man ska skriva ett meddelande så borde ju
 *  menyn för teckensnitt osv synas. Nu ligger den långt ner så man behöver
 *  scrolla ner."
 *
 * That was the first one, and this block used to answer it by sticking the
 * toolbar to the BOTTOM of the scroller, one button-row height up
 * (`bottom: var(--rt-bar-offset, 3.4rem)`). Measured at 390 wide it worked:
 * at 360 tall - roughly what is left of a phone once the keyboard is up - the
 * bar's bottom edge sat 54px INSIDE the layout viewport rather than 145px
 * below it.
 *
 * Then it was reported a second time, from a deployed build, photographed in
 * both Safari iOS and Firefox iOS:
 *
 * "När man klickar i skrivfönstret zoomas bilden in en bit och verktygsfältet
 *  längst försvinner."
 *
 * ## Why the first fix could not have held
 *
 * Because "the bottom of the scroller" is not the bottom of the screen on a
 * telephone, and three separate things made the gap between them big enough
 * to swallow the whole row:
 *
 *   1. WebKit zooms the page in whenever a focused editable computes below
 *      16px, which shrinks the VISUAL viewport while the layout viewport
 *      stands still. Both photographs are WebKit - Firefox on iOS is WKWebView
 *      underneath - which is why one browser did not disagree with the other.
 *      Answered by the font sizes at the foot of this file.
 *   2. Without `interactive-widget=resizes-content` in the viewport meta the
 *      layout viewport keeps its full height when the keyboard opens, so
 *      ANYTHING anchored to its bottom is behind the keyboard by construction.
 *      Answered in each host's <head>.
 *   3. `--rt-bar-offset` was never set by either host, and it had to be: the
 *      customer's panel button row measures 149.6px tall at 390 wide (it wraps
 *      - Send, attach, a checkbox with a sentence beside it, cancel), against
 *      a 54.4px default taken from Mission Control. So on that host the
 *      toolbar was drawn 95px INSIDE the row it was supposed to sit above,
 *      underneath it, with a lower z-index. Nobody had to open a keyboard for
 *      that one.
 *
 * (1) and (2) are fixed here and are fixes we cannot watch happen: neither can
 * be observed from a Linux checkout, and both depend on iOS behaving the way
 * its documentation says. (3) is a number that was simply wrong.
 *
 * ## So it moves, and the argument that put it at the bottom survives
 *
 * A row ABOVE the text cannot be behind the keyboard in any browser, ever,
 * with no meta tag and no measurement - the keyboard comes up from the bottom
 * and the browser scrolls the caret clear of it, so everything above the caret
 * is on the screen by definition. That is the whole reason for the move: this
 * is the third time this row has been placed and it should be the last.
 *
 * The first complaint was that the toolbar was BELOW THE FOLD, not that it was
 * at the top - and `top: 0` inside the same scroller answers it more completely
 * than `bottom` ever did, because a sticky top edge cannot scroll away in
 * either direction. The `.rt-toggle` that opens it stays down in the button
 * row beside the paperclip, where the thumb is and where Gmail puts it; only
 * the row it opens moves, to where the text it formats actually is.
 *
 * The cost, stated rather than hidden: pressing Aa at the bottom of the screen
 * makes a row appear at the top of it, and the text shifts down by the row's
 * height. That is why the narrow-screen rule below stops it wrapping - measured
 * at 390 wide, three wrapped lines was 84.2px on mail and 111.4px on the panel,
 * against 42.6px for a single scrolling row.
 *
 * ## The z-index is 1, and it is not an arbitrary small number
 *
 * The rule has always been "if the two rows ever meet, the BUTTON ROW wins" -
 * it holds Send, and a toolbar covering Send is a worse bug than the one being
 * fixed here. This said 29, which was chosen against Mission Control's
 * `.compose-bar` at 30 and is wrong on the other host: the customer's panel
 * puts `.mbx-compose__bar` at z-index 5, so 29 covered it.
 *
 * They do meet. A sticky top and a sticky bottom collide as soon as the pane
 * is shorter than their combined content, which on the panel is 43px of bar
 * against a 149.6px button row - observed overlapping at 390x360 and at
 * 852x390, both of which are ordinary phone shapes with a keyboard open.
 *
 * So the number has to be under the LOWER of the two rows, not the higher, and
 * it still has to beat the message text scrolling underneath - which is not
 * positioned at all, so anything from 0 up does that. Hence 1. Raising it to
 * tidy it up puts the formatting row over Send on one host only, which is the
 * kind of fault that gets found by a customer.
 */
.rt-bar {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .15rem;
  /* Lined up with the message's own left edge, not with the pane's. */
  padding: .3rem 1.2rem;
  border: 1px solid var(--rt-line, rgba(127, 127, 127, .25));
  /* Open at the top now rather than at the bottom: it hangs off the addressed
     rows above it instead of sitting on the button row below. */
  border-top: 0;
  border-radius: 0 0 8px 8px;
  background: var(--rt-sunk, #f3f4f6);
}

.rt-bar__split {
  width: 1px;
  align-self: stretch;
  margin: .15rem .3rem;
  background: var(--rt-line, rgba(127, 127, 127, .25));
}
.rt-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 32px square: the smallest a finger can reliably hit, and the figure both
     hosts' icon buttons already use. */
  min-width: 32px;
  height: 32px;
  padding: 0 .4rem;
  border: 1px solid transparent;
  border-radius: 6px;
  background: none;
  color: inherit;
  font: inherit;
  line-height: 1;
  cursor: pointer;
}
.rt-btn:hover { background: var(--rt-hover, rgba(127, 127, 127, .12)); }
.rt-btn:focus-visible {
  outline: 2px solid var(--rt-accent, #2563eb);
  outline-offset: 1px;
}
/* Pressed means the caret is inside text that already has it. Read back from
   the document on every selection change, not remembered - a toolbar that
   thinks bold is on while the cursor sits in plain text is worse than one that
   shows nothing. */
.rt-btn[aria-pressed="true"] {
  border-color: var(--rt-line, rgba(127, 127, 127, .25));
  background: var(--rt-hover, rgba(127, 127, 127, .18));
}
.rt-btn--b { font-weight: 700; }
.rt-btn--i { font-style: italic; }
.rt-btn--u { text-decoration: underline; }
.rt-btn--s { text-decoration: line-through; }

/* The size and typeface pickers. `max-width` because a font name can be long
   and a select that grows to its longest option turns the toolbar into two
   rows the moment somebody picks Courier New. */
.rt-pick {
  height: 32px;
  max-width: 8.5rem;
  border: 1px solid transparent;
  border-radius: 6px;
  background: none;
  color: inherit;
  font: inherit;
  font-size: .85rem;
}
.rt-pick:hover { background: var(--rt-hover, rgba(127, 127, 127, .12)); }

/* ---------------------------------------------------------------------------
   The writing surface

   It stands in for a textarea, so it has to BEHAVE like one.

   `flex: 1` is the half of this rule that matters, and both hosts learned it
   separately. Mission Control's `.compose-body` had it and grew to fill the
   pane; this had a fixed `min-height` instead, so hiding the textarea and
   putting this in its place left forty per cent of the compose pane as dead
   grey below the button row. The customer's panel had the same rule on its
   `.mbx-compose__body` and this file had no rule at all, so the box had no
   height whatsoever and the message area was simply missing.

   No border and no radius, for the same reason: the PANE is the box. Neither
   host's textarea drew one, and a bordered rectangle inside a bordered
   rectangle is what it looked like.
   --------------------------------------------------------------------------- */
.rt {
  flex: 1;
  min-height: 12rem;
  padding: 1rem 1.2rem;
  border: 0;
  background: none;
  overflow-y: auto;
  font: inherit;
  line-height: 1.55;
  color: var(--rt-ink, inherit);
}
/* No ring. The pane itself is what somebody is typing into - a box drawn round
   the whole writing area every time the cursor lands in it is a box that never
   goes away. */
.rt:focus { outline: none; }
.rt:empty::before {
  content: attr(data-placeholder);
  color: var(--rt-muted, #6b7280);
  pointer-events: none;
}
.rt a { color: var(--rt-accent, #2563eb); }
.rt ul, .rt ol { padding-left: 1.5rem; margin: .4rem 0; }
.rt blockquote {
  margin: .5rem 0;
  padding-left: .8rem;
  border-left: 3px solid var(--rt-line, rgba(127, 127, 127, .25));
  color: var(--rt-muted, #6b7280);
}

/* ---------------------------------------------------------------------------
   The emoji sheet and the link field

   Both hang off the toolbar and both are ordinary flow content rather than
   floating panels, because a popover that escapes an `overflow: auto` pane is
   a popover clipped in half.

   They open on the side of the bar the TEXT is on, which is what they have
   always done - it was upward while the bar was anchored to the bottom, and it
   is downward now that the bar sits above the writing area. The DOM order that
   decides it is `bar.after(sheet, linkRow)` in rich-text.js; the borders here
   have to agree with it, or the sheet draws a hairline through the bar it is
   attached to.
   --------------------------------------------------------------------------- */
.rt-sheet {
  display: flex;
  flex-wrap: wrap;
  gap: .1rem;
  padding: .4rem 1.2rem;
  border: 1px solid var(--rt-line, rgba(127, 127, 127, .25));
  border-top: 0;
  background: var(--rt-sunk, #f3f4f6);
}
.rt-sheet button {
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: 6px;
  background: none;
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
}
.rt-sheet button:hover { background: var(--rt-hover, rgba(127, 127, 127, .12)); }

.rt-link {
  display: flex;
  gap: .4rem;
  padding: .4rem 1.2rem;
  border: 1px solid var(--rt-line, rgba(127, 127, 127, .25));
  border-top: 0;
  background: var(--rt-sunk, #f3f4f6);
}
.rt-link input { flex: 1 1 auto; min-width: 0; }

/* ===========================================================================
 * THE TELEPHONE, LAST IN THE FILE AND DELIBERATELY SO
 *
 * ## Why one block, and why here
 *
 * Every rule below has to BEAT a rule written above it, and at equal
 * specificity that is decided by position and by nothing else. `.rt` carries
 * `font: inherit` in its own block; `.rt-bar` carries `flex-wrap: wrap` in
 * its. A media query adds no specificity whatever, so a phone rule written
 * beside the element it corrects is a phone rule that loses - silently, with
 * the source reading as though the fault were fixed.
 *
 * That is not a hypothetical: it is exactly how this bug survived its first
 * fix. mail.css carried `@media (max-width: 560px) { .cfield__box { font-size:
 * 16px } }`, with a comment naming this very screen, and it applied to nothing
 * because `.cfields .cfield__box { font: inherit }` further up is one class
 * sharper. All four addressed rows stayed at 15px and went on zooming.
 * mail.css puts its widths last for the same reason and says so; this file
 * does it now too.
 *
 * ## The gate: two clauses, and the second is not the same question
 *
 * `pointer: coarse` is "this device puts a keyboard over the bottom of the
 * screen", which is the thing that actually matters and which a width cannot
 * ask - an iPhone held sideways is 852px wide and behaves exactly like one
 * held upright. The width clause is there so a desk browser dragged narrow
 * gets the row that fits, and so that neither clause failing on its own can
 * leave this unfixed a third time.
 * ======================================================================== */
@media (pointer: coarse), (max-width: 700px) {
  /* -------------------------------------------------------------------------
   * One toolbar row that scrolls sideways, rather than three that wrap
   *
   * Wrapping was harmless while the bar was anchored to the bottom - it grew
   * away from the text. At the top it grows INTO the writing area and pushes
   * the caret down by its whole height the moment somebody presses Aa, which
   * on a phone is the difference between the caret being above the keyboard
   * and behind it. Measured at 390 wide: 84.2px on mail and 111.4px on the
   * panel, against 42.6px for a single row.
   *
   * The same answer `.msg-bar` and `.bulk-bar` already give at these widths,
   * and for the same reason: a row of icons that does not fit is a row you
   * push sideways, not a block of icons three deep. Nothing is clipped away
   * with no way to reach it.
   * ---------------------------------------------------------------------- */
  .rt-bar {
    flex-wrap: nowrap;
    overflow-x: auto;
    /*
     * `flex: none`, and it is not tidying - without it this row is TEN PIXELS
     * TALL.
     *
     * The same trap `.msg-bar` and `.rail` each have a note about, arriving
     * from the other side: `overflow-x: auto` computes `overflow-y` to `auto`
     * as well, and a flex item whose overflow is not `visible` loses its
     * automatic minimum size. This bar is a flex item of the compose form, the
     * form is a column shorter than its content, so with nothing to stop it
     * the bar shrank to its own padding and the buttons hung out of it.
     * Measured at 390x360: 10.6px of bar around 32px buttons.
     */
    flex: none;
    /* No scrollbar eating a row of height, as everywhere else on these
       screens. */
    scrollbar-width: none;
  }
  .rt-bar::-webkit-scrollbar { display: none; }
  /* And the controls do not squash either: `nowrap` still lets every item
     shrink below its content, which turns twelve buttons into twelve slivers
     rather than a row that scrolls. */
  .rt-bar > * { flex: none; }

  /*
   * "There is more this way."
   *
   * Measured at 390 wide: 709px of controls inside 388px of bar on mail and
   * 827px on the panel, so more than half the row is off to the right with
   * nothing to say so. The rail strip on the phone layout had exactly this
   * reported - a pill cut in half at an edge and no sign there was anything
   * past it - and this is the same answer it settled on: a sticky
   * pseudo-element painting its own gradient, NOT a `mask-image`. A mask
   * applies to the whole painted subtree, and the day somebody positions a
   * child of this bar outside it a mask would erase it with every measurement
   * still reading correct. That one cost a screenshot to find.
   *
   * Negative margin so it takes no width, `pointer-events: none` so it is not
   * a dead strip over the last button.
   */
  .rt-bar::after {
    content: "";
    position: sticky;
    right: 0;
    z-index: 2;
    flex: 0 0 1.2rem;
    align-self: stretch;
    margin-inline-start: -1.2rem;
    pointer-events: none;
    background: linear-gradient(to left, var(--rt-sunk, #f3f4f6), transparent);
  }

  /* -------------------------------------------------------------------------
   * THE SIZES A PHONE WILL NOT ZOOM
   *
   * "När man klickar i skrivfönstret zoomas bilden in en bit och
   *  verktygsfältet längst försvinner."
   *
   * Every WebKit browser on iOS - which is Safari AND Firefox AND Chrome
   * there, because they are all WKWebView, which is why the operator's two
   * photographs agreed - zooms the page in when a focused editable computes
   * below 16px. It is not a preference and there is no way to turn it off
   * short of `user-scalable=no`, which is a WCAG 1.4.4 failure and which
   * test/mobile-viewport.test.js exists to catch somebody reaching for.
   *
   * The zoom is a whole half of the reported bug on its own: it shrinks the
   * visual viewport, so everything anchored near an edge moves further out of
   * reach. It is also the half that makes the screen LOOK broken rather than
   * badly laid out, because the page visibly jumps the instant a finger lands
   * in the message.
   *
   * Sixteen exactly, and only on the elements a finger can land in. Raising a
   * host's `body` to 16px would answer this too, and would re-set the density
   * of two entire applications to solve something that lives in four elements
   * per screen.
   *
   * These three are this file's OWN elements, so they are fixed here for both
   * hosts at once. Each host's own fields - the addressed rows, the subject,
   * the search box - carry that host's names and are fixed in that host's
   * stylesheet; the split is the whole point of this file and is written out
   * at the top of it.
   *
   * Measured in Chromium at 390 wide, before: `.rt` 15px on both hosts,
   * `.rt-link input` 13.33px on both (the browser's own default - nothing had
   * ever given it a size), `.rt-pick` 13.6px on mail and 14.4px on the panel.
   * ---------------------------------------------------------------------- */

  /* The message itself, and the one element the complaint actually names. */
  .rt { font-size: 16px; }
  /* The address somebody pastes into the link row. */
  .rt-link input { font-size: 16px; }
  /*
   * iOS zooms for a focused <select> as well, not only for text fields. The
   * row keeps its 32px height, so what changes is the text inside the two
   * pickers and not the height of the bar.
   *
   * Written as two classes, and it has to be. The customer's panel styles its
   * form controls with `.adm select`, which is (0,1,1) and beats a bare
   * `.rt-pick` at (0,1,0) wherever either is written - measured: still 14.4px
   * with the one-class version, on the host that has that rule. This is the
   * exact hazard mailbox-head.ejs already warns about for `.adm button`
   * against `.rt-btn`. A picker only ever exists inside the bar, so naming
   * both is true rather than a specificity trick.
   */
  .rt-bar .rt-pick { font-size: 16px; }
}
