/* The floor a control and a label have to clear before a phone counts as
 * supported.
 *
 * All three signed-in areas were drawn on a 1440px canvas by a design tool,
 * and a design tool has no opinion about thumbs. The layouts themselves
 * survive the trip down to 390px — the portal's artboard folds its own grids
 * and slides its rail off-canvas, and src/admin-links.css does the same for
 * the console — but the sizes came along unchanged. So what is left at phone
 * size is a product that looks right and cannot be operated: rail items 38px
 * tall in a list you scroll with the same thumb you are trying to tap with, a
 * menu button at 34px square, badges at 9.5px, table headers at 10.5px, and
 * text inputs small enough that iOS zooms the page the moment one is focused
 * and never zooms back out.
 *
 * Three numbers, and each of them is somebody's published floor rather than a
 * preference:
 *
 *   44px   Apple's Human Interface Guidelines, for the smallest thing a
 *          finger should be asked to hit. Android's Material guidance says
 *          48dp; 44 is the stricter of the two to satisfy in CSS pixels and
 *          the one both platforms' own controls are built to.
 *
 *   11.5px is not a published floor — there is no such number — but it is
 *          where the design system's own smallest token sits, and everything
 *          under it in these three applications got there by being scaled
 *          down from a canvas rather than by being chosen.
 *
 *   16px   is the size at or above which mobile Safari will not zoom the
 *          viewport when a field takes focus. Below it the page jumps, and
 *          because nothing zooms it back, every subsequent tap lands in the
 *          wrong place. It is the one number here that is a browser
 *          behaviour rather than a guideline.
 *
 * Which elements need which is a question about their rendered size, and CSS
 * cannot ask that. src/mobile.js measures and marks; everything below is what
 * a mark means. The same bargain src/portal-ui.css and src/admin-links.css
 * already make, for the same reason: these applications style themselves
 * inline from React, so overriding them means !important and knowing which
 * element to name.
 *
 * The breakpoint is 900px rather than the portal's own 760, because a control
 * too small for a finger is too small on a tablet as well — nothing here
 * changes a layout, only the size of the things you touch and read, and there
 * is no width at which those should go back to being smaller.
 */

@media (max-width: 900px) {
  /* Grown to a finger.
  
     A minimum is the whole override, and deliberately so. `min-height` is not
     in competition with the inline `height` it is raising — the box's height
     is worked out from `height` and then clamped by `min-height`, so 38px
     inline and 44px here settle at 44 without either winning. Forcing
     `height: auto` as well does win, and takes with it every control sized as
     a fraction of something: the bars of the dashboard's output chart are
     `height: 100%` of a 118px well, and released to `auto` they collapse to
     the label underneath them. */
  [data-fz-tap] { min-height: 44px !important; }

  /* A control carrying an icon and no more than a character or two — a
     burger, a bell, an avatar, a close — is as easy to miss sideways as it is
     vertically, so it is squared off rather than stretched. */
  [data-fz-tap="icon"] { min-width: 44px !important; }

  /* And the label in the middle of the box, not at the top of it.
     The minimum above grows a box downwards, so a raised link kept its words
     where they were and gained 24px of reach underneath them — a box hanging
     below its own label, over whatever is next in the list. Which side the
     words go is the element's own text-align, carried across because flex
     ignores it. src/mobile.js marks only the boxes whose content is all
     inline, so becoming a flex container moves nothing else. */
  [data-fz-centre] {
    display: flex !important;
    align-items: center !important;
  }
  [data-fz-centre="middle"] { justify-content: center !important; }
  [data-fz-centre="end"] { justify-content: flex-end !important; }

  [data-fz-small] { font-size: 11.5px !important; }

  /* Reachable by panning, for a table that will not fit however it is asked.
     The card holding the portal's invoices is `overflow: hidden` inline, to
     keep a square-cornered table inside a rounded card, and that clipped the
     two right-hand columns away with nothing to reach them by. Only the
     sideways axis is released, so the corners still clip. */
  [data-fz-pan] {
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
  }

  /* And worth panning once it is pannable. Squeezed to the width of the card,
     every cell wrapped — an invoice number over three lines, a date over two,
     a row four times as tall as it needed to be and harder to read than the
     scroll it was avoiding. 520px is the width the console already gives its
     own tables, so the two applications ask a thumb for the same movement. */
  [data-fz-pan] > table { min-width: 520px; }

  /* Anything you can type into. The exclusions are the inputs that have no
     text in them to size. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  select,
  textarea {
    font-size: 16px !important;
  }

  /* Collapsing a rail is a desktop affordance. Below the breakpoint the rail
     is a drawer, and both artboards force it back to full width while it is
     one — so the control is still there, still tappable, and does nothing.
     src/admin-links.css says the same thing about the console's copy of this
     button; the mark here is the portal's. */
  [data-fz-collapse] { display: none !important; }

  /* Every dialog in all three areas is centred in a fixed, full-screen flex
     box with a desktop frame of padding around it, and sized for a desktop:
     540px for the portal's pipeline modal, 680 for the console's drawer,
     1160 for a work card. On a 390px screen the frame is a tenth of the
     width spent on a strip of the page behind — which is not context, only
     somewhere to mis-tap — and the height is whatever the content came to,
     because 86vh of a phone is shorter than 86vh of a laptop.

     So a dialog takes the screen, less enough of a frame to still read as
     one thing lying on top of another, and scrolls inside itself rather than
     running off the bottom. dvh rather than vh because a phone browser's
     address bar is part of the viewport by the first measure and not by the
     second, and the difference is the height of a button. */
  div:has(> [role="dialog"]) { padding: 8px !important; }
  [role="dialog"] {
    width: 100% !important;
    max-width: none !important;
    max-height: calc(100vh - 16px) !important;
    max-height: calc(100dvh - 16px) !important;
    padding-bottom: env(safe-area-inset-bottom) !important;
  }
}
