/* Mobile and tablet layout.
 *
 * Loaded last so it overrides the desktop rules without editing them: the Electron app
 * is always above these breakpoints and renders exactly as before, while the browser
 * client reflows down to a phone.
 *
 * Two things drive every rule here:
 *   · touch has no hover, so anything revealed by :hover must be permanently visible
 *   · a 38px single-line row cannot hold a title, chips and controls at 360px wide,
 *     so rows become two-line blocks rather than shrinking their text
 */

/* ── TOUCH: hover-revealed controls must not be reachable only by hover ───── */
@media (hover: none) {
  .strip { opacity: 1; }
  .row-tools { width: auto; }
  /* · the desktop board reveals row actions on hover; on touch they are always shown */
  .row .row-btn,
  .row .row-more { opacity: 1; }
  /* · same rule for the band's quick-add and a lane card's menu button — both were
   *   only ever revealed by :hover, so a touch device could never see them at all */
  .band-add,
  .lc-more { opacity: 1; }
}

/* ── TABLET ───────────────────────────────────────────────────────────────── */
@media (max-width: 860px) {
  .ws-tiles { grid-template-columns: repeat(2, 1fr); }
  .ws-cards { grid-template-columns: 1fr; }

  /* · admin tables are emitted as bare <table> with no wrapper, so the table itself is
   *   the scroll container: `display:block` is what gives overflow-x something to act
   *   on, since a table box ignores it */
  .ws-table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
  }
}

/* ── PHONE ────────────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
  /* · dvh, not vh: mobile browser chrome shrinks the viewport as it hides, and vh
   *   leaves a gap the user can scroll into */
  #shell { height: 100dvh; }

  /* the nav rail becomes a bottom bar — thumbs reach the bottom, not the left edge */
  #app { flex-direction: column-reverse; }
  /* · #app's main axis is now vertical, so #main's height goes through the flex-shrink
   *   algorithm instead of desktop's row-layout stretch. Without min-height:0 here, its
   *   auto-minimum is its content's full size, so #scroll-area (which does shrink; it
   *   has overflow:auto) never receives a constrained height to shrink INTO — #main
   *   balloons to fit every row instead, busting the board out past the viewport top
   *   instead of scrolling internally. */
  #main { min-height: 0; }
  #rail {
    width: 100%;
    flex: 0 0 auto;
    flex-direction: row;
    justify-content: space-around;
    align-items: center;
    border-right: 0;
    border-top: 1px solid var(--line);
    padding: 4px 0;
    padding-bottom: max(4px, env(safe-area-inset-bottom));
    overflow-x: auto;
  }
  #rail > * { flex: 0 0 auto; }

  /* the header keeps only identity and the day picker */
  #dayhead { padding: 0 8px; gap: 6px; }
  #app-identity span:not(.app-icon-sm) { display: none; }
  #caption-gap { display: none; }
  #layout-seg { display: none; }
  #task-filter-wrap { min-width: 0; flex: 1 1 auto; }
  /* · its only content, the standup/status grouping toggle, already moves into the
   *   ⋯ menu below 1120px — an empty 48px bar is not worth the vertical space here */
  .board-header { display: none; }

  /* rows: two lines, so the title never competes with chips for width */
  .row {
    height: auto;
    min-height: 52px;
    flex-wrap: wrap;
    align-items: flex-start;
    padding: 10px 12px;
    gap: 6px;
  }
  .row-title {
    flex: 1 1 100%;
    white-space: normal;
    overflow-wrap: anywhere;
    line-height: 1.35;
  }
  .chips { flex: 1 1 auto; flex-wrap: wrap; gap: 5px; }
  .row-tools { flex: 0 0 auto; width: auto; margin-left: auto; }

  /* · 44px is the smallest reliably tappable target */
  .row-more,
  .dh-arrow { min-width: 44px; min-height: 44px; }
  /* · row-btn carries its own visible border, so stretching it to 44px with the
   *   desktop's 22px-row padding/font left a tall, near-empty pill; padding and type
   *   grow with it instead so the tap target and the label read as one proportioned
   *   button rather than a stretched sliver of text */
  .row-btn {
    height: auto;
    min-height: 40px;
    padding: 9px 14px;
    font-size: var(--font-size-sm);
  }
  /* · every real button, not just the board's: the sign-in gate and the nav rail are
   *   the first things a phone user touches */
  .btn,
  .btn-pri,
  .btn-sec,
  .btn-primary,
  .btn-secondary,
  #rail button,
  #rail a { min-height: 44px; }

  /* · these carry an explicit `height` from an ID rule, which min-height cannot raise:
   *   the height itself has to be replaced, at matching specificity */
  #btn-slack-signin,
  .auth-gate-buttons .btn { height: 44px; }
  .strip i { width: 16px; height: 16px; }
  .strip { gap: 8px; }

  /* modals go full-bleed: a centred card wastes a phone screen */
  .modal,
  .modal-sm,
  .modal-lg {
    width: 100%;
    max-width: 100%;
    max-height: 100dvh;
    height: 100dvh;
    border-radius: 0;
    border-left: 0;
    border-right: 0;
  }
  .modal-body { overflow-y: auto; -webkit-overflow-scrolling: touch; }
  .modal-footer { padding-bottom: max(12px, env(safe-area-inset-bottom)); }
  .modal-footer button { min-height: 44px; }

  /* · iOS zooms the whole page when a focused input is under 16px, and never zooms back.
   *   The class and id selectors below are listed explicitly because a bare `input`
   *   rule loses to .form-input and #task-filter on specificity. */
  input, select, textarea,
  .form-input, .form-textarea, .form-select,
  .ws-form input, .ws-form select,
  #task-filter,
  #dayhead input { font-size: 16px; }

  .ws-tiles { grid-template-columns: 1fr; }
  .ws-form input, .ws-form select { flex: 1 1 100%; }

  /* · the inline task editor's Team/Due/Ticket grid and every modal's two-up form
   *   row are 3 and 2 columns built for desktop widths; at 360px each cell is too
   *   narrow for its own input, so both stack to one column per field */
  .ex-grid,
  .form-row { grid-template-columns: 1fr; }

  /* · the import canvas is a raw-text pane and a parsed-preview pane side by side;
   *   on a phone width the parsed pane would be squeezed to nothing, so the two
   *   stack instead, each scrolling its own content */
  .imp { flex-direction: column; }
  .imp-raw { flex: 1 1 50%; min-height: 160px; border-right: 0; border-bottom: 1px solid var(--line); }
  .imp-out { width: 100%; flex: 1 1 50%; min-height: 160px; }

  /* · a fixed 340px card is wider than the viewport on the narrowest phones;
   *   the gate itself gains the gutter so the card keeps breathing room */
  #auth-gate { padding: 0 16px; }
  #auth-gate-card { width: 100%; max-width: 340px; }

  /* the Slack preview is a pane on desktop; on a phone it is its own screen */
  #preview-pane { display: none; }
}
