/* public/assets/css/responsive-polish.css
 *
 * Second-pass mobile polish, layered on top of ui-globals.css's two systemic
 * fixes (the `.flex` wrap safety net and the `grid-cols-N` auto-fit reflow).
 * Those two already fixed the worst offender reported from a real device
 * (Infinix Hot50, ~360-412px CSS width) — squeezed 2-6 column stat-card
 * grids — but the same pass turned up four more classes of bug that the
 * grid fix doesn't reach, listed below. This file is additive; it does not
 * duplicate anything already handled in ui-globals.css or
 * responsive-tables.css.
 *
 *   1. Page/section headings (`<h1 class="text-2xl">Student Management</h1>`
 *      -style — the de-facto heading convention almost everywhere in this
 *      app) don't scale down, so a 24-36px heading eats a big chunk of a
 *      360px-wide screen and can force the header row to wrap awkwardly.
 *
 *   2. A couple of icon-in-a-box components size the box smaller than the
 *      icon inside it (views/web/about.php + views/web/home.php's `w-6 h-6`
 *      feature boxes holding a `text-3xl` FontAwesome icon) — the icon
 *      overflows its own box at ANY viewport width, not just mobile. It's
 *      the same "icon dominating a small container" symptom from the bug
 *      report, so it's fixed here alongside the rest of the icon work
 *      rather than filed separately.
 *
 *   3. Icon-only action buttons — the table-row "Edit"/"Delete" pattern: a
 *      `<button>`/`<a>` whose entire content is one `<i class="fas ...">`
 *      with no visible label — commonly ship with little or no padding, so
 *      their real tap target is just the glyph itself. That's well under
 *      the 44px minimum the project's own frontend-theme-and-responsive-ui
 *      skill requires, and per that skill's own checklist this had not
 *      actually been audited anywhere in the app yet.
 *
 *   4. Ad-hoc summary/KPI cards (`rounded-lg border ... p-4`, `.stat-card`)
 *      built as an icon-box + text flex row can get pushed wider than their
 *      card — and the card wider than the viewport — by one long unbroken
 *      string (a long school or guardian name), because flex items default
 *      to `min-width: auto`. This is independent of the grid-cols squeeze
 *      the earlier fix solved: it happens even to a card that's alone in a
 *      single mobile column.
 *
 * Scope: intended to be loaded once from each layout `<head>` alongside
 * ui-globals.css and responsive-tables.css (wiring TBD by whoever picks
 * this up next). Wherever a selector targets a Tailwind utility class, it
 * uses `[class~="..."]` (exact class-token match) for the same reason
 * ui-globals.css's grid-cols fix does: `~=` only fires on the literal
 * unprefixed token, so a responsive-prefixed variant like `md:text-3xl`
 * is never accidentally caught.
 *
 * Section 3 relies on the CSS `:has()` relational selector (Chrome/Edge
 * 105+, Safari 15.4+, Firefox 121+ — universally available on real phones
 * by now). Browsers without it simply skip that rule; nothing breaks, the
 * icon-only buttons just don't get the extra tap-target padding, same as
 * before this file existed.
 */

/* ── 1. Heading sizing ────────────────────────────────────────────────────
 * `text-2xl` / `text-3xl` / `text-4xl` on `h1`/`h2`/`h3` is the page- and
 * section-title convention across the app — an unprefixed `text-2xl` alone
 * appears on an `<h1>` in ~197 view files (e.g. "Student Management" in
 * views/dashboard/students/index.php:41), `text-3xl`/`text-4xl` mixed in on
 * `<h2>`/`<h3>` in dozens more. Far too pervasive and far too consistent a
 * pattern to hand-edit — but also consistent enough to be one rule.
 *
 * Deliberately scoped to the heading tags themselves, not a blanket
 * `.text-2xl` rule: unrelated uses of the same utility class — stat-card
 * dollar values, hero body copy, badges — must NOT shrink, so the selector
 * only fires when the class sits on an actual `h1`/`h2`/`h3` element. */
@media (max-width: 767px) {
  h1[class~="text-4xl"], h2[class~="text-4xl"], h3[class~="text-4xl"] {
    font-size: 1.5rem;    /* 36px -> 24px */
    line-height: 1.3;
  }
  h1[class~="text-3xl"], h2[class~="text-3xl"], h3[class~="text-3xl"] {
    font-size: 1.375rem;  /* 30px -> 22px */
    line-height: 1.3;
  }
  h1[class~="text-2xl"], h2[class~="text-2xl"], h3[class~="text-2xl"] {
    font-size: 1.25rem;   /* 24px -> 20px */
    line-height: 1.3;
  }
}

/* ── 2. Icon-in-a-box overflow ────────────────────────────────────────────
 * views/web/about.php (2x) and views/web/home.php (3x) size a feature-card
 * icon box `w-6 h-6` (24px square) but the icon inside is `text-3xl`
 * (30px font-size) — bigger than the box holding it, at every viewport.
 * Only 5 occurrences across 2 marketing pages that reuse the same
 * copy-pasted card block, so — per the "check breadth first" rule — a
 * narrow selector is the right call here, not a broad `text-3xl` override.
 * Not gated to a mobile media query on purpose: the mismatch isn't caused
 * by squeezing, it's wrong at 1280px too, just more cramped-looking on a
 * phone. */
[class~="w-6"][class~="h-6"] > i[class~="text-2xl"],
[class~="w-6"][class~="h-6"] > i[class~="text-3xl"],
[class~="w-6"][class~="h-6"] > i[class~="text-4xl"] {
  font-size: 0.875rem; /* comfortably inside a 24px box, matches icon-14px norm */
  line-height: 1;      /* FontAwesome's default line-height overshoots a box this
                           small even once font-size is capped — pin it so the
                           icon's own box stays inside its 24px parent too */
}

/* ── 3. Icon-only button tap targets (mobile) ────────────────────────────
 * The table action-column pattern used throughout the app (views/root/
 * root-admins.php's Edit/Remove icon buttons, views/root/registration-
 * pins.php's delete button, views/dashboard/calendar/index.php's Edit/
 * Delete buttons, views/dashboard/results/assessments.php, etc.): a
 * `<button>` or `<a>` whose only content is a single `<i class="fas ...">`,
 * no visible label. Padding on these ranges from generous (`p-2`) to none
 * at all (just text-color classes) — several ship with literally no
 * padding, so the real tap target is the bare glyph, far under the 44px
 * minimum the project's frontend-theme-and-responsive-ui skill calls for.
 *
 * `:has(> i.fas:only-child)` identifies "icon, and nothing else" precisely:
 * `:only-child` matches only when the icon is the sole *element* child, so
 * a labeled button like `<button><i class="fas fa-money-bill-wave"></i>
 * <span>Pay</span></button>` (views/dashboard/students/index.php's Pay/View
 * actions) is correctly left alone — that `<i>` has a `<span>` sibling, so
 * it isn't `:only-child`, so the button keeps its existing shape. A few
 * buttons write the label as bare trailing text instead of a `<span>`
 * (`<i class="fas fa-edit mr-1"></i>Edit`) — those still pick up the min
 * tap-target box here too, which only makes them easier to hit, never
 * worse, and the rule stays mobile-only so desktop is untouched either way. */
@media (max-width: 767px) {
  a:has(> i.fas:only-child),
  a:has(> i.far:only-child),
  a:has(> i.fab:only-child),
  button:has(> i.fas:only-child),
  button:has(> i.far:only-child),
  button:has(> i.fab:only-child),
  [role="button"]:has(> i.fas:only-child),
  [role="button"]:has(> i.far:only-child),
  [role="button"]:has(> i.fab:only-child) {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
}

/* ── 4. Card text / flex-child overflow ──────────────────────────────────
 * `.stat-card` and the ad-hoc `rounded-lg border ... p-4` card pattern (19
 * occurrences across 11 files, e.g. views/dashboard/third-party-payments/
 * index.php's KPI cards) are almost always built as an icon-box + text flex
 * row. Flex items default to `min-width: auto`, meaning a long unbroken
 * string inside the text half (a long school or guardian name, a long
 * payee name) can force that child — and the card, and potentially the
 * whole page — wider than the viewport instead of wrapping. This is a
 * separate mechanism from the grid-cols squeeze already fixed: it can
 * happen even to a single card alone on its own row at mobile width, where
 * the grid-cols reflow doesn't come into play at all.
 *
 * `min-width: 0` on the card removes the implicit "never shrink below my
 * content" floor so it can actually respect its parent's width; the same
 * on the flex row's direct children (text block AND icon box — harmless on
 * the icon box since it already has an explicit fixed width) lets long text
 * wrap inside the card instead of pushing past its edge. `overflow-wrap`
 * is inherited, so setting it once on the card catches any nested
 * paragraph/span without needing to enumerate them. */
@media (max-width: 767px) {
  .stat-card,
  [class~="rounded-lg"][class~="border"][class~="p-4"] {
    min-width: 0;
    overflow-wrap: break-word;
  }

  .stat-card > [class~="flex"] > *,
  [class~="rounded-lg"][class~="border"][class~="p-4"] > [class~="flex"] > * {
    min-width: 0;
  }
}

/* ── 5. Button text/padding reduction (tablet and below) ─────────────────
 * Full-size desktop button padding (`px-4 py-2`, `px-6 py-3`, etc. — the
 * dominant button-sizing convention app-wide: 2000+ occurrences across 200+
 * files) reads oversized on a tablet or phone and can misshape a card/row
 * that's already tight on width (a button refusing to shrink is exactly
 * what forces its container, and sometimes the whole row, wider than it
 * should be). This scales the common padding/text-size utility combinations
 * down on `button`/`a`/`[role=button]`/submit-ish `input` elements at
 * <=1024px — "starting from tablets", matching the same breakpoint as the
 * filter drawer and the tab-sizing rule below.
 *
 * Exact-token (`[class~=...]`) selectors, same reasoning as every other
 * rule in this file and in ui-globals.css: a substring match would also
 * catch responsive-prefixed variants like `md:px-6`.
 *
 * Deliberately excludes icon-only buttons (`:has(> i.fas:only-child)` etc.)
 * — those are handled by rule 3 above, which *enforces a 44px minimum*,
 * the opposite direction from this rule. Excluding them here means the two
 * rules can never fight over the same element.
 *
 * Written as flat, explicit selectors (no CSS nesting) to match this
 * project's existing plain-CSS convention everywhere else. */
@media (max-width: 1024px) {
  button:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="px-6"],
  a[class*="rounded"]:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="px-6"],
  [role="button"]:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="px-6"] {
    padding-left: 0.875rem !important;
    padding-right: 0.875rem !important;
  }

  button:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="px-4"],
  a[class*="rounded"]:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="px-4"],
  [role="button"]:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="px-4"] {
    padding-left: 0.625rem !important;
    padding-right: 0.625rem !important;
  }

  button:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="px-3"],
  a[class*="rounded"]:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="px-3"],
  [role="button"]:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="px-3"] {
    padding-left: 0.5rem !important;
    padding-right: 0.5rem !important;
  }

  button:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="py-3"],
  a[class*="rounded"]:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="py-3"],
  [role="button"]:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="py-3"] {
    padding-top: 0.5rem !important;
    padding-bottom: 0.5rem !important;
  }

  button:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="py-2"],
  a[class*="rounded"]:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="py-2"],
  [role="button"]:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="py-2"] {
    padding-top: 0.375rem !important;
    padding-bottom: 0.375rem !important;
  }

  button:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="py-1.5"],
  a[class*="rounded"]:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="py-1.5"],
  [role="button"]:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="py-1.5"] {
    padding-top: 0.3125rem !important;
    padding-bottom: 0.3125rem !important;
  }

  button:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="text-base"],
  a[class*="rounded"]:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="text-base"],
  [role="button"]:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="text-base"] {
    font-size: 0.8125rem !important;
  }

  button:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="text-sm"],
  a[class*="rounded"]:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="text-sm"],
  [role="button"]:not(:has(> i.fas:only-child)):not(:has(> i.far:only-child)):not(:has(> i.fab:only-child))[class~="text-sm"] {
    font-size: 0.75rem !important;
  }

  input[type="submit" i][class~="px-6"], input[type="button" i][class~="px-6"] { padding-left: 0.875rem !important; padding-right: 0.875rem !important; }
  input[type="submit" i][class~="px-4"], input[type="button" i][class~="px-4"] { padding-left: 0.625rem !important; padding-right: 0.625rem !important; }
  input[type="submit" i][class~="px-3"], input[type="button" i][class~="px-3"] { padding-left: 0.5rem !important; padding-right: 0.5rem !important; }
  input[type="submit" i][class~="py-3"], input[type="button" i][class~="py-3"] { padding-top: 0.5rem !important; padding-bottom: 0.5rem !important; }
  input[type="submit" i][class~="py-2"], input[type="button" i][class~="py-2"] { padding-top: 0.375rem !important; padding-bottom: 0.375rem !important; }
}

/* ── 6. Header button-groups: 2-3 actions stay in one row on phones ──────
 * The page-header pattern used throughout the app — e.g. students/index.php's
 * "Import Students" / "Register Student" pair — is a `<div class="flex
 * gap-2">` of 2-3 `inline-flex`-styled action buttons/links. Left to
 * ui-globals.css's blanket flex-wrap safety net alone, a pair like this can
 * wrap onto separate lines on a narrow phone even after rule 5's padding
 * reduction, because the two full-width-ish buttons still don't both fit.
 * The user asked for these to stay in a row, shrinking instead of stacking —
 * same "small group stays in a row" philosophy as the <=3-tab rule in
 * ui-globals.css, applied here to button toolbars via the same quantity-
 * query trick (`:nth-child(-n+3):last-child` — true only when the container
 * has <=3 matching children).
 *
 * `:where(a, button)` keeps the selector list from exploding into an a/
 * button cross-product (`:where()` contributes zero specificity, so this is
 * purely a shorthand, not a specificity change).
 *
 * Deliberately gated on `[class~="inline-flex"]` — a header button-group
 * always has that on its children in this app (it's how the icon+label
 * pairs are aligned), so this doesn't accidentally match unrelated flex
 * rows of 3-or-fewer arbitrary children (e.g. a 2-column form row). */
@media (max-width: 767px) {
  .flex:has(> :where(a, button)[class~="inline-flex"]:nth-child(-n+3):last-child):not(.overflow-x-auto) {
    flex-wrap: nowrap !important;
    gap: 6px;
  }

  .flex:has(> :where(a, button)[class~="inline-flex"]:nth-child(-n+3):last-child)
    > :where(a, button)[class~="inline-flex"] {
    font-size: 11px !important;
    padding: 6px 8px !important;
    white-space: nowrap;
  }

  .flex:has(> :where(a, button)[class~="inline-flex"]:nth-child(-n+3):last-child)
    > :where(a, button)[class~="inline-flex"] i {
    font-size: 11px !important;
  }
}
