/* ══════════════════════════════════════════════════════════════════════════
   lms-responsive.css — builder-mobile
   Cross-cutting mobile pass over the whole portal. This file touches
   selectors owned by app.css / layouts/app.blade.php (the shell, nav, forms,
   buttons) WITHOUT editing those shared files — every rule here overrides by
   loading after them, and several rules deliberately use a compound selector
   (tag+class, or two classes) so the override holds even if load order ever
   changes. No colours, no new motion — sizing, spacing and overflow only.

   Requested by: .claude/handoff/allocation.md, builder-mobile brief.
   Ledger: this file must be linked from resources/views/layouts/app.blade.php
   AFTER lms-foundation.css and AFTER @stack('styles') closes, so its rules
   win the cascade against every per-page stylesheet. See
   .claude/handoff/shared/builder-mobile.md.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── page-level safety net ───────────────────────────────────────────────
   Every inner scrollable region below (`.tbl`, `.anav`, tab bars, modals)
   already contains its own overflow-x. This is the backstop for anything
   that still slips through — a page must never grow a horizontal scrollbar
   of its own on a phone, no matter which component caused it. */
/* `overflow-x` on `html` only, deliberately not `body` too: per the CSS
   Overflow spec, when one axis is non-visible and the other is left at its
   default `visible`, the browser silently promotes the visible one to
   `auto` — setting `overflow-x:hidden` on `body` (which also carries
   `min-height:100vh; display:flex` from app.css) would make body itself
   the scrolling container instead of the viewport, and risks the sticky
   header (`.abar{position:sticky}`) computing its containing block wrong.
   `html` alone is the standard, footgun-free way to kill page-level
   horizontal scroll.
   Scoped to `@media screen`: admin/reports/trainee.blade.php (the printable
   progress report) renders through layouts/app.blade.php, so once this file
   is linked from the layout, an unscoped rule here would also reach paged
   media — clipping content the print engine should instead be left to
   handle on its own terms, on the one report this project expects printed.
   The certificate print view is a separate self-contained document that
   never links this file and is unaffected either way. */
@media screen {
  html {
    overflow-x: hidden;
  }
  img, svg, video, iframe {
    max-width: 100%;
  }
}

/* ── header shell: the ACTUAL mobile bug ─────────────────────────────────
   app.css's existing 820px rule sets `.anav{order:3;width:100%}` expecting
   the nav to drop to its own row, but `.abar__in` is never given
   `flex-wrap:wrap` anywhere — so today, on any phone, the flex items only
   shrink against each other instead of wrapping, and the header can spill
   past the viewport edge. This is the fix that rule was always missing. */
@media (max-width: 820px) {
  header.abar .abar__in {
    flex-wrap: wrap;
    row-gap: 6px;
  }
}

/* At phone widths the brand mark + 4 header icons + locale pill no longer
   fit on one row even after wrapping the nav away — trim them down rather
   than let them wrap again (a 3-row header eats too much vertical space on
   a 360px screen where every pixel of scroll room matters). */
@media (max-width: 480px) {
  header.abar .abar__in {
    gap: 8px;
  }
  header.abar .abar__brand {
    gap: 8px;
  }
  header.abar .abar__brand .m {
    width: 28px;
  }
  /* the small letter-spaced caption under the wordmark — decorative, first
     to go when width is tight */
  header.abar .abar__brand > span > span {
    display: none;
  }
  header.abar .abar__end {
    gap: 4px;
  }
  header.abar .iconbtn {
    width: 36px;
    height: 36px;
  }
  header.abar .iconbtn .ico {
    width: 16px;
    height: 16px;
  }
}

/* ── the last pixels: one header row down to 360px ───────────────────────
   B6. lms-nav.css gives `.abar__end` `flex-wrap:wrap` below 900px as a
   genuine last-resort fallback, and the block above trims the cluster at
   480px — but measured on the trainee bar (the widest: avatar, bell, locale
   pill, search, theme, logout) the row still broke at 374px and stayed
   broken at 360px, with the logout form alone on a second line and the
   header growing 73px → 113px. 360px is a very common Android width.

   The gap here is bridged by taking a few pixels off each of the four
   things that share the row, rather than dropping a control: every one of
   them is the only route to what it opens. The wrap itself is deliberately
   NOT removed — below ~350px there genuinely is not room, and a wrapped
   header is still better than a clipped one.

   Selectors are written to out-specify (and, loading last, out-order) both
   app.css and lms-nav.css, whose own rules for these elements are (0,2,1)
   and (0,3,0). */
@media (max-width: 400px) {
  header.abar .abar__in {
    padding-inline: 12px;
  }
  /* lms-nav.css reserves `--pad + 48px` at the inline start for the fixed
     burger. The burger is 40px wide and sits at `inset-inline-start:12px`
     once the padding above applies, so 44px clears it with a 4px gutter
     instead of the desktop 48px + a 20px --pad. */
  html:has(.lms-sidebar) header.abar .abar__in {
    padding-inline-start: 56px;
  }
  header.abar .abar__end {
    gap: 2px;
  }
  header.abar .iconbtn {
    width: 34px;
    height: 34px;
  }
  /* The locale pill is two options wide; its desktop inline padding is the
     single biggest saving left on the row. The 40px tap floor set in
     lms-foundation.css at 600px is untouched — this trims width only. */
  header.abar .lms-locale__opt {
    padding-inline: 8px;
  }
  /* The avatar is already the whole chip below 820px (lms-profile.css hides
     `.who__id`); this is the last 6px of its frame. */
  header.abar .who--link {
    padding: 1px;
  }
}

/* ── .tbl--stack: a wide table becomes a card list on a phone ─────────────
   B1. `.tbl` is an `overflow-x:auto` wrapper over a `min-width:640px`
   table, which contains the overflow but gives no affordance that it
   scrolled — measured on /portal/tasks at 375px, «فتح» sat entirely
   off-viewport and the page had no vertical scroll either, so a trainee on
   a phone could not open a task at all. Same for «تسجيل الحضور» on the
   timetable.

   The mechanic is the one lms-payments.css already proved on the statement
   ledger, promoted here as an opt-in primitive so the three remaining
   portal tables share it instead of each growing a private copy. Opt-in
   rather than blanket `.tbl`, because a table only stacks legibly when its
   cells actually carry `data-label` — an unlabelled table stacked this way
   loses its column names entirely.

   `min-width:0` is load-bearing: app.css's `.tbl table{min-width:640px}`
   floor keeps forcing 640px through a 375px viewport even after the rows
   become blocks, which is exactly how the statement's receipt column stayed
   off-screen before that file added the same line. A stacked card list has
   no columns left to protect.

   640px matches the statement's breakpoint and sits above every phone
   width; the desktop table is untouched. */
@media (max-width: 640px) {
  .tbl--stack table,
  .tbl--stack tbody,
  .tbl--stack tr,
  .tbl--stack td { display: block; width: auto; }

  .tbl--stack table { min-width: 0; }

  /* The header row's words move into each cell's ::before, so the row
     itself is removed from view but kept in the accessibility tree. */
  .tbl--stack thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }

  .tbl--stack tr {
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    padding: 4px 12px;
  }
  .tbl--stack tr + tr { margin-block-start: 10px; }

  .tbl--stack td[data-label] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 7px 0;
    text-align: start;
    border-block-end: 0;
  }
  .tbl--stack td[data-label] + td[data-label] { border-block-start: 1px solid var(--border); }
  .tbl--stack td[data-label]::before {
    content: attr(data-label);
    color: var(--text-muted);
    font-size: .82rem;
    flex: 0 0 auto;
  }

  /* An action cell carries no data-label (there is no column name worth
     repeating over a button) and takes the full card width, so the primary
     action of the row is a full-width target rather than a link crushed
     against the card edge. `.cell-actions`'s desktop `white-space:nowrap`
     would otherwise keep two stacked buttons on one unbreakable line. */
  .tbl--stack td.cell-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    white-space: normal;
    padding: 10px 0 6px;
    border-block-start: 1px solid var(--border);
    border-block-end: 0;
  }
  .tbl--stack td.cell-actions .btn { flex: 1 1 auto; justify-content: center; }
}

/* The nav.anav scroll-strip block that lived here (SCOPE NOTE D1 + the
   1599px pill rail) is DELETED — D-080 moved the trainee onto the shared
   sidebar rail, the layout no longer emits nav.anav anywhere, and the
   block's own comment named a real hamburger as "the alternative if a real
   toggle is wanted later". It is wanted now, and it exists. */

/* ── forms: 16px floor stops iOS Safari auto-zooming on focus ───────────
   app.css's `.f` inputs are .97rem (~15.5px) — under the 16px line Safari
   uses to decide whether to zoom. Selector is written to match (and thus
   safely beat, once `html` is added) app.css's own `.f input[type=…]`
   specificity of (0,2,1) — a bare `input[type=…]` rule would lose that
   fight regardless of stylesheet order. Scoped to real text-entry controls
   only, so icon buttons and pill tabs (also <button>/<input>) are
   untouched. */
@media (max-width: 600px) {
  html .f input[type="text"], html .f input[type="email"], html .f input[type="tel"],
  html .f input[type="password"], html .f input[type="number"], html .f input[type="date"],
  html .f select, html .f textarea,
  input[type="search"] {
    font-size: 16px;
  }
}

/* ── tap targets: 44px floor on the primary action controls ─────────────
   Header icon buttons are handled above (with their own smaller-but-still-
   ≥44px-effective sizing, since four of them plus the locale pill must
   share one row); everywhere else on a touch screen, buttons grow to the
   accessible minimum instead of staying at their desktop `.btn--sm` size. */
@media (max-width: 600px) {
  .btn {
    min-height: 44px;
  }
  .iconbtn {
    min-width: 44px;
    min-height: 44px;
  }
  header.abar .iconbtn {
    /* header keeps its own compaction rule above — do not re-grow it here */
    min-width: 0;
    min-height: 0;
  }
  html .check input {
    width: 22px;
    height: 22px;
  }
}

/* ── notification-preferences table (portal.notifications.prefs) ────────
   `.ln-prefs` belongs to lms-notifications.css, owned by a unit building
   right now — rules for it live here instead, per the brief. Two checkbox
   columns plus a label column is narrow enough to never need horizontal
   scroll; the fix needed is a bigger checkbox hit-area, not a layout
   change. */
@media (max-width: 600px) {
  .ln-prefs td, .ln-prefs th {
    padding: 12px 10px;
  }
  .ln-prefs td input[type="checkbox"] {
    width: 22px;
    height: 22px;
  }
}

/* ── admin rubric editor row (lms-tasks.css, owned by another unit) ─────
   `.rubric-editor__row` is a fixed `1fr 140px auto` grid — the middle
   points column stays a usable width down to ~360px, but combined with the
   label column and the remove-row control it gets tight rather than
   broken. Stack to one column below 480px so the points input and remove
   button never crowd the label on the narrowest phones, per the brief. */
@media (max-width: 480px) {
  .rubric-editor__row {
    grid-template-columns: 1fr;
  }
}
