/* ui-responsive.css -- the mobile floor under every page of the app.
 *
 * WHY THIS FILE EXISTS
 * Each template carries its own <style> block, written desktop-first. That
 * is fine for layout, but it means the same three mobile mistakes were
 * repeated thirteen times and fixed nowhere. This file is loaded LAST in
 * <head> -- after the page's own <style> -- so a rule here wins against a
 * page rule of equal specificity without needing !important everywhere.
 *
 * It only ever *raises* a floor. Nothing here shrinks, hides or moves
 * anything: every rule is a minimum, and on a desktop the whole mobile
 * block is inert. Every selector below was measured against a real page
 * first; nothing is here on speculation.
 *
 * The three standards it implements:
 *   1. Form controls at 16px on touch widths. Safari on iOS zooms the
 *      whole page in when you focus a control whose font-size is under
 *      16px, and it does not zoom back out. Every control in this app
 *      measured between 12.8px and 15.7px.
 *      https://css-tricks.com/16px-or-larger-text-prevents-ios-form-zoom/
 *   2. WCAG 2.2 SC 2.5.8 Target Size (Minimum), level AA: an interactive
 *      target is at least 24x24 CSS pixels. Radios measured 13x13,
 *      labels 20px tall, back-links 21px.
 *      https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum
 *   3. A readable floor on small type. Persian at 11.5px on a phone is
 *      not small, it is unread.
 */

/* ------------------------------------------------------------------ *
 * Every width. These are not mobile rules, they are correctness rules
 * that happen to bite hardest on a phone.
 * ------------------------------------------------------------------ */

html {
  /* Safari inflates text when a page rotates to landscape unless it is
     told not to. `100%` keeps the user's own zoom working -- `none`
     would break pinch-to-zoom, which is an accessibility failure. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* A long URL, a Latin email address or an unbroken phone number is the
   usual cause of a page that scrolls sideways on a 360px screen. */
body { overflow-wrap: break-word; }

/* Media never exceeds its column; `height:auto` keeps the aspect ratio
   when the width is the constraint.

   NOT iframes, and not canvases. THIS BROKE THE THEME PICKER.
   The preview and the comparison thumbnails render the customer's site
   at a real desktop width -- 1440px, or 320% of the card -- and then
   scale the whole frame down, on purpose: an iframe the width of the
   panel would show the theme's TABLET design, which is not the design
   being bought. `max-width: 100%` clamped that 1440px frame to the
   1002px panel, so the site inside rendered at its tablet breakpoint
   and then got scaled by the 0.696 that was computed for 1440 -- a
   page two-thirds the width of its own frame, pinned to the right,
   with three hundred pixels of nothing beside it.

   An oversized iframe is always deliberate, because somebody had to
   type its width. An oversized image is almost always an accident. */
img, svg, video { max-width: 100%; height: auto; }

/* NAVIGATION LINKS, AT EVERY WIDTH.
   WCAG 2.2 SC 2.5.8 exempts a link that sits inside a sentence, because
   moving it would reflow the sentence. It does not exempt the small
   standalone links this app uses as navigation -- "خروج", "داشبورد من",
   "‹ داشبورد", "بازگشت به صفحه‌ی اصلی" -- which measured 20 to 22
   pixels tall on every page that has a top bar. They are controls, and
   a control is 24x24 whether the pointer is a finger or a mouse.

   Three pixels of vertical padding is the whole fix: the links already
   sit in a flex row with a gap, so nothing moves and nothing collides.
   It is deliberately a short, named list rather than `a` -- a blanket
   rule would inflate the nav bars and the footer columns. */
.topbar a,
.who a,
a.link,
a.home-link,
a.szs-back,
.alt a,
.hint a,
.sub a,
.foot a,
.note a {
  display: inline-block;
  min-height: 24px;
  padding-block: 3px;
}

/* ------------------------------------------------------------------ *
 * Touch widths.
 * 899px and not 768px: a portrait tablet is still a finger.
 * ------------------------------------------------------------------ */
@media (max-width: 899px) {

  /* --- 1. iOS zoom-on-focus ------------------------------------- *
     Colour, radio, checkbox, range and file are excluded: they have no
     text to zoom to, and forcing a font-size on them changes their
     painted size in some browsers.

     `!important` and not just load order: the pages set these sizes
     through class selectors -- `.hero-form textarea`, `.szs-role-select`
     -- which outrank a bare element selector no matter which file loads
     last. A floor that loses the cascade is not a floor. It is scoped to
     a media query and to form controls, so it cannot leak anywhere
     else. */
  input:not([type="radio"]):not([type="checkbox"]):not([type="color"]):not([type="range"]):not([type="file"]),
  select,
  textarea {
    font-size: 16px !important;
  }

  /* --- 2. Target size, 24x24 ------------------------------------ */

  /* Checkboxes and radios ship at 13x13. 20px for the control plus the
     label padding below clears 24 comfortably, and the control stays
     visually proportionate to 16px text. */
  input[type="radio"],
  input[type="checkbox"] {
    width: 24px !important;
    height: 24px !important;
    accent-color: var(--ui-primary, #4260E6);
  }

  /* Vertical padding on an inline element still enlarges its hit area
     without pushing the line box around, so a label sitting inline next
     to a radio grows from 20px to 26px, and a block label simply gets a
     little more room. The 2px on the sides is for the short ones --
     a colour-swatch label reading "text" is 21.5px wide. */
  label {
    padding-block: 3px;
    padding-inline: 2px;
  }

  /* Colour swatches and other icon-sized buttons. Scoped to <button>
     on purpose: a "dot" in this app is just as often a decorative
     status light (`.szs-dot` is an 8px circle in the editor header),
     and blowing that up to 24px is a bug, not a fix. */
  button.style-dot,
  button.swatch,
  button[class*="-dot"],
  button[class*="-swatch"] {
    min-width: 24px;
    min-height: 24px;
  }

  /* Controls get an explicit floor. */
  button,
  input[type="submit"],
  input[type="button"],
  input[type="reset"],
  input[type="radio"],
  input[type="checkbox"],
  select,
  summary,
  textarea,
  input:not([type]),
  input[type="text"], input[type="email"], input[type="password"],
  input[type="tel"], input[type="url"], input[type="search"],
  input[type="number"], input[type="color"], input[type="date"] {
    min-height: 24px;
  }

  /* A link inside a running paragraph is exempt from SC 2.5.8 (the
     "inline" exception), but it is still easier to hit with three
     pixels of padding, and on a phone every paragraph link is a
     thumb target. Kept inside the media query because inline-block
     stops a link wrapping across two lines, which matters in long
     desktop prose and not on a narrow column. */
  p > a {
    display: inline-block;
    min-height: 24px;
    padding-block: 3px;
  }

  /* --- 3. A floor under small type ------------------------------- */
  small,
  .hint, .note, .url, .sub, .addr,
  .szs-hint,
  [class*="badge"],
  .preview-expand,
  figcaption {
    font-size: max(12.5px, 0.78rem) !important;
  }

  /* --- 4. Room to breathe ---------------------------------------- */

  /* The cards on this app are padded 40-44px on the sides; on a 360px
     screen that is a quarter of the width spent on air. */
  .box, .card, .panel, .szs-panel { padding-inline: max(18px, 4vw); }

  /* A grid or flex item is `min-width:auto` by default, which means one
     wide child can push its track past the viewport and take the whole
     document sideways with it. The editor's sidebar is the case here:
     the panel's own side padding plus a 24px tap target was eight
     pixels more than a 360px screen. */
  .szs-layout > *, .szs-sidebar > * { min-width: 0; }

  /* Notched phones: the home indicator sits over the last 34px of the
     viewport, so anything pinned to the bottom needs to clear it. */
  body { padding-bottom: env(safe-area-inset-bottom, 0px); }
}

/* ------------------------------------------------------------------ *
 * Small phones. 360px is the floor of the Android market; the iPhone SE
 * is 375.
 * ------------------------------------------------------------------ */
@media (max-width: 400px) {
  .box, .card, .panel, .szs-panel {
    padding-inline: 16px;
    border-radius: 16px;
  }
}

/* ------------------------------------------------------------------ *
 * Coarse pointers, at any width. A phone plugged into a monitor, a
 * tablet in landscape, a touchscreen laptop: the finger does not get
 * more precise because the window got wider.
 * ------------------------------------------------------------------ */
@media (pointer: coarse) {
  button,
  input[type="submit"],
  input[type="button"],
  select,
  summary,
  [role="button"] {
    min-height: 24px;
  }
  input[type="radio"],
  input[type="checkbox"] {
    min-width: 20px;
    min-height: 20px;
  }
}
