/* ═══════════════════════════════════════════════════════════════════
   MOBILE RESPONSIVE LAYER · LearnerConnect HR
   Loaded LAST so it can override the inline rules in index.html.
   Breakpoints stay on the project convention: 1024 / 768 / 640 / 480.
   Sidebar mobile behaviour lives in /css/sidebar.css — do not duplicate.
   =================================================================== */

/* ═══════════════════════════════════════════════════════════════════
   ENTERPRISE MOBILE FOUNDATION — global guards, safe-area, touch.
   Sits at the top so component rules below can still override it.
   =================================================================== */

/* Hard stop for app-wide horizontal overflow. `clip` (not `hidden`)
   so it never becomes a scroll container that would break the sticky
   topbar / sticky modal heads. Contained scroll inside .tbl-wrap is
   unaffected (that overflow lives on the wrapper, not the page). */
html, body { overflow-x: clip; }

/* Media can never exceed its box. NOTE: `table` is deliberately
   excluded — wide tables rely on .tbl-wrap's own horizontal scroll. */
img, svg, video, canvas, iframe, pre { max-width: 100%; }

/* ─── Grid / flex min-content blowout guard ──────────────────────
   Grid & flex items default to min-width:auto, so they refuse to
   shrink below their content's min-content. A wide child (a long
   <select> option, an unbreakable hint string, a native file input)
   then forces its track — and the whole card — WIDER than the
   viewport. overflow-x:clip hides the scrollbar so it looks fine in a
   scrollWidth check but the content is visibly clipped on the right.
   Letting layout items shrink is the canonical fix and preserves the
   intended column counts. Scoped to phone/tablet widths. */
@media (max-width: 768px) {
  .grid2 > *, .grid3 > *, .form-grid > *,
  .card, .form-field,
  .profile-summary-grid > *, .profile-section-grid > *,
  .dash-activity-grid > *, .today-grid > *, .announcement-grid > * {
    min-width: 0;
  }
  .form-field input,
  .form-field select,
  .form-field textarea { max-width: 100%; }
  .upload-note, .field-hint, .form-hint, .help-text { overflow-wrap: anywhere; }
}

/* Long unbroken strings (emails, IDs, URLs, file paths) wrap instead
   of spilling out of cards/cells. Scoped to text surfaces so it never
   fights intentional nowrap on chips/buttons/truncated titles. */
@media (max-width: 768px) {
  .card p, .card li, td,
  .ns-row-main, .notif-feed-item,
  .profile-summary-card strong,
  .profile-meta-chip,
  .org-fallback-card,
  .ai-chat-msg,
  code, .mono {
    overflow-wrap: anywhere;
    word-break: break-word;
  }
}

/* ─── Safe-area insets (notched iPhone, installed PWA) ───────────
   env() resolves to 0 without insets, so these are harmless additive
   paddings elsewhere. Requires viewport-fit=cover in <meta viewport>. */
@media (max-width: 1024px) {
  /* NOTE: the topbar notch inset lives on the base .topbar rule in
     index.html's inline <style> — that block loads AFTER this file,
     so a .topbar{padding-top} rule here would lose the cascade and be
     dead. Do not re-add one; fix it at the source instead. */
  .sidebar {
    padding-top: env(safe-area-inset-top);
    padding-bottom: env(safe-area-inset-bottom);
  }
  /* Sidebar nav rows: real ≥44px touch rows + inertial scroll */
  .sb-item { min-height: 44px; display: flex; align-items: center; }
  .sb-nav { -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
}
@media (max-width: 768px) {
  #toast { margin-bottom: env(safe-area-inset-bottom); }
}

/* ─── Universal touch targets ≥44px (≤768) ──────────────────────
   The pre-existing 44px rule only covered .btn / .form-field inputs.
   These interactive chips/switches/toolbar buttons were 24–34px. */
@media (max-width: 768px) {
  .ns-chip,
  .ns-bulk-btn,
  .mr-chip,
  .quick-add-chip,
  .org-toolbar button,
  .ai-chat-send,
  .ai-chat-mic,
  .ai-chat-icon-btn {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .topbar-ico-btn { min-height: 40px !important; min-width: 40px; }
}

/* ─── Shared table-as-cards (opt in with class="tbl-cards") ────────
   Collapses 7+ column tables into a stacked card list on narrow
   screens. Requires each <td> to have data-label="Column name". */
@media (max-width: 640px) {
  .tbl-cards { margin: 0 !important; padding: 0 !important; overflow: visible !important; }
  .tbl-cards table,
  .tbl-cards thead,
  .tbl-cards tbody,
  .tbl-cards tr,
  .tbl-cards th,
  .tbl-cards td { display: block; width: 100%; box-sizing: border-box; }
  .tbl-cards thead { display: none; }
  .tbl-cards tr {
    padding: 14px 16px 16px;
    border: 1px solid var(--border);
    border-radius: 14px;
    margin-bottom: 12px;
    background: var(--surface);
    box-shadow: var(--shadow-xs);
  }
  .tbl-cards tr:last-child { margin-bottom: 0; }

  /* Field = label on top (small caps, muted) + value below it, left
     aligned and readable. Replaces the old far-apart label/value
     split that read like a raw data dump. */
  .tbl-cards td {
    display: block;
    padding: 10px 0 0;
    border: 0;
    font-size: 14px;
    line-height: 1.45;
    color: var(--text);
    text-align: left;
    max-width: none !important;
    white-space: normal !important;
    overflow-wrap: anywhere;
  }
  .tbl-cards td::before {
    content: attr(data-label);
    display: block;
    font-weight: 700;
    color: var(--muted);
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    margin-bottom: 3px;
  }

  /* First cell = the card header: prominent name/title, no label
     chip, a divider beneath. Turns a generic field list into a real
     profile-style card. */
  .tbl-cards td:first-child {
    font-size: 17px;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--text);
    padding: 0 0 12px;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--border);
  }
  .tbl-cards td:first-child::before { display: none; }
  .tbl-cards td:first-child > div {
    display: flex;
    align-items: center;
    gap: 12px;
  }

  /* Empty-state row (single colspan td): plain centred text, never a
     card header. */
  .tbl-cards td[colspan] {
    text-align: center !important;
    font-size: 13px !important;
    font-weight: 400 !important;
    border: 0 !important;
    padding: 18px 0 !important;
    margin: 0 !important;
  }
  .tbl-cards td[colspan]::before { display: none; }

  /* Actions → a full-width wrapping button row; buttons share the
     width so the last one never clips off the card edge. */
  .tbl-cards td[data-label="Action"],
  .tbl-cards td[data-label="Actions"] {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding-top: 14px;
  }
  .tbl-cards td[data-label="Action"]::before,
  .tbl-cards td[data-label="Actions"]::before { flex: 1 1 100%; margin-bottom: 4px; }
  .tbl-cards td[data-label="Action"] > div,
  .tbl-cards td[data-label="Actions"] > div {
    display: flex; flex-wrap: wrap; gap: 8px; flex: 1 1 100%;
  }
  .tbl-cards td[data-label="Action"] .btn,
  .tbl-cards td[data-label="Action"] .btn-sm,
  .tbl-cards td[data-label="Action"] .btn-xs,
  .tbl-cards td[data-label="Actions"] .btn,
  .tbl-cards td[data-label="Actions"] .btn-sm,
  .tbl-cards td[data-label="Actions"] .btn-xs {
    flex: 1 1 auto;
    min-width: 88px;
    justify-content: center;
  }
}

/* ─── Small-tablet tweaks (≤768px) ─────────────────────────────── */
@media (max-width: 768px) {
  /* Give table cells more breathing room when horizontal scroll is used */
  .tbl-wrap td, .tbl-wrap th { padding: 10px 8px; font-size: 12.5px; }

  /* Profile section grid — stack columns */
  .profile-section-grid { grid-template-columns: 1fr !important; }

  /* Calendar cards tighten already; ensure legend wraps */
  .calendar-legend { flex-wrap: wrap; gap: 6px; }
}

/* ─── Phone breakpoint (≤480px) ────────────────────────────────── */
@media (max-width: 480px) {
  /* Forms collapse to a single column so no labels overflow */
  .form-grid { grid-template-columns: 1fr !important; }

  /* Stats collapse cleanly — auto-fit minmax(180px) was pushing cards to overflow */
  .stats { grid-template-columns: 1fr 1fr !important; }

  /* Today-grid / announcement-grid — single column, no min-width issues */
  .today-grid,
  .announcement-grid { grid-template-columns: 1fr !important; }

  /* Profile summary-grid already goes 2col at 480; keep consistent */
  .profile-summary-grid { grid-template-columns: 1fr 1fr !important; }

  /* Summary pills wrap cleanly without minimum widths forcing overflow */
  .summary-pills { gap: 8px; }
  .summary-pill { min-width: 0; flex: 1 1 calc(50% - 8px); padding: 10px 12px; }

  /* Accessibility — tap targets to 44px minimum */
  .btn,
  .btn-sm,
  .btn-xs { min-height: 44px; }
  /* Topbar icon buttons should still stay compact */
  .topbar-ico-btn { min-height: 34px; }
  /* Tiny action buttons inside table cards can stay slightly smaller but >=38 */
  .tbl-cards td .btn-xs,
  .tbl-cards td .btn-sm { min-height: 38px; padding: 8px 12px; }

  /* Page header content + actions stack cleanly */
  .page-header {
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 10px !important;
  }
  .page-header > div:last-child {
    width: 100%;
    flex-wrap: wrap !important;
    overflow: visible !important;
    gap: 8px;
  }
  .page-header .btn,
  .page-header .btn-sm { width: auto; flex: 0 1 auto; }
  .profile-header-actions { width: 100%; justify-content: flex-start; flex-wrap: wrap; }

  /* Form actions stretch — already set at 480 but reinforce consistency */
  .form-actions { flex-wrap: wrap; }

  /* Grid2 — single col at phone */
  .grid2 { grid-template-columns: 1fr !important; }

  /* Calendar tweaks for horizontal grid fallback */
  .calendar-grid { gap: 3px; }
  .calendar-day { min-height: 64px; padding: 4px; }

  /* Filter rows (inline flex) wrap cleanly */
  .card > div[style*="display:flex"][style*="flex-wrap:wrap"] .form-field { flex: 1 1 100%; min-width: 0; }

  /* Profile hero gets looser padding to avoid avatar crowding */
  .profile-hero { padding: 1rem; }
  .profile-hero-main { gap: 12px; }
  .profile-meta-row { flex-wrap: wrap; gap: 6px; }

  /* AI box / office banner tighten */
  .office-banner { padding: .9rem 1rem; }
}

/* ─── Calendar-as-list for narrow screens (≤640px) ────────────────
   The month grid of 7 micro-cells becomes an ugly blur on phones.
   At ≤640px we re-flow it into a vertical list, one day per row.
   The weekday header row and is-empty placeholders are hidden. */
@media (max-width: 640px) {
  /* The weekday header grid sits in #checkin-calendar-head — hide it. */
  #checkin-calendar-head.calendar-grid { display: none; }

  .calendar-grid {
    display: flex !important;
    flex-direction: column;
    gap: 8px;
  }
  .calendar-day {
    min-height: 0;
    flex-direction: row;
    align-items: flex-start;
    gap: 12px;
    padding: 10px 12px;
    border-radius: 10px;
  }
  .calendar-day.is-empty { display: none; }
  .calendar-date-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    min-width: 48px;
    flex-shrink: 0;
  }
  .calendar-date-row strong { font-size: 18px; }
  .calendar-date-row span {
    display: block !important;
    font-size: 10.5px;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: .06em;
  }
  .calendar-events {
    flex: 1 1 auto;
    gap: 4px;
    min-width: 0;
  }
  .calendar-event {
    font-size: 12px;
    padding: 5px 10px;
    border-radius: 7px;
    line-height: 1.35;
    white-space: normal;
  }
}

/* ─── Notifications feed & policies — no regressions ─────────────
   Kept minimal; these already render as cards, just ensure
   content does not overflow on very small screens. */
@media (max-width: 480px) {
  .notif-feed > li { padding: 12px !important; }
  .announcement-card { padding: 1rem; }
  .announcement-top { flex-wrap: wrap; gap: 6px; }
}

/* ─── Payroll page (≤768px) ──────────────────────────────────────
   The salary editor + payslips table both get wide fast. tbl-cards
   class on the tables + this block handles the cramped widths. */
@media (max-width: 768px) {
  /* The salary history is a narrow 7-col table inside the editor —
     force horizontal scroll rather than wrap. */
  #pr-salary-history-body {
    font-size: 12px;
  }
  #pr-salary-editor .tbl-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* Commissions contracts → card-per-contract on phones, consistent
     with agents/imports. Bespoke (not generic .tbl-cards) because of
     the chevron toggle, the draft bulk-checkbox, the colspan expand
     row and the group-header rows. Collapsed .cc-exp-row keeps its
     inline display:none (inline beats this rule — intended). */
  #cc-tbl-wrap, #cc-tbl-wrap table, #cc-tbl-wrap tbody,
  #cc-tbl-wrap tr, #cc-tbl-wrap td {
    display: block; width: 100%; box-sizing: border-box;
  }
  #cc-tbl-wrap thead { display: none; }
  #cc-tbl-wrap table { min-width: 0; }

  /* Group-by-university header → plain section label */
  #cc-tbl-wrap tr.cc-group-header { background: transparent !important; border: 0 !important; }
  #cc-tbl-wrap tr.cc-group-header td { padding: 16px 2px 6px !important; }

  /* Each contract = a card */
  #cc-tbl-wrap tr.cc-data-row {
    position: relative;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: var(--surface);
    box-shadow: var(--shadow-xs);
    padding: 14px 16px 16px;
    margin-bottom: 12px;
  }
  /* Chevron expand toggle → compact top-right control */
  #cc-tbl-wrap tr.cc-data-row td.cc-cell-chevron {
    position: absolute; top: 8px; right: 8px;
    width: auto !important; padding: 0 !important;
  }
  #cc-tbl-wrap .cc-row-toggle {
    min-height: 36px; min-width: 36px; font-size: 16px !important;
  }
  /* Draft bulk-checkbox → top-left (hidden when the row isn't a draft) */
  #cc-tbl-wrap tr.cc-data-row td.cc-cell-check { width: auto !important; padding: 0 !important; }
  #cc-tbl-wrap td.cc-cell-check:empty { display: none; }
  #cc-tbl-wrap td.cc-cell-check:not(:empty) {
    position: absolute; top: 12px; left: 12px;
  }
  #cc-tbl-wrap td.cc-cell-check input { width: 20px; height: 20px; margin: 0; }
  /* University = card header (label-over-value style matches the
     global .tbl-cards redesign on agents/imports) */
  #cc-tbl-wrap tr.cc-data-row td.cc-cell-uni {
    font-size: 16px; font-weight: 700; letter-spacing: -0.01em;
    padding: 0 40px 12px 0; margin-bottom: 8px;
    border-bottom: 1px solid var(--border);
    overflow-wrap: anywhere;
  }
  #cc-tbl-wrap td.cc-cell-check:not(:empty) + td.cc-cell-uni { padding-left: 30px; }
  /* Data fields: small-caps label on top, value below */
  #cc-tbl-wrap tr.cc-data-row td[data-label] {
    padding: 9px 0 0; font-size: 14px; text-align: left;
    overflow-wrap: anywhere;
  }
  #cc-tbl-wrap tr.cc-data-row td[data-label]::before {
    content: attr(data-label); display: block;
    color: var(--muted); font-size: 10.5px; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.07em; margin-bottom: 3px;
  }
  /* Actions → full-width wrapping button row */
  #cc-tbl-wrap tr.cc-data-row td.cc-cell-actions {
    display: flex !important; flex-wrap: wrap; gap: 8px;
    padding-top: 14px; white-space: normal !important;
  }
  #cc-tbl-wrap tr.cc-data-row td.cc-cell-actions .btn {
    flex: 1 1 auto; min-width: 96px; justify-content: center;
  }
  /* Expanded detail panel → flush continuation under its card */
  #cc-tbl-wrap tr.cc-exp-row { margin: -12px 0 12px; }
  #cc-tbl-wrap tr.cc-exp-row > td { padding: 0 !important; }
  #cc-tbl-wrap tr.cc-exp-row > td > div {
    border: 1px solid var(--border); border-top: 0;
    border-radius: 0 0 14px 14px;
  }
  #cc-tbl-wrap tr.cc-exp-row table { min-width: 0; font-size: 12px; }
}

@media (max-width: 480px) {
  /* Payslip action column has two buttons — wrap them */
  #pr-payslips-body td[data-label="Actions"] > div {
    flex-wrap: wrap;
    gap: 6px;
  }
  /* Leave Master form grid at 480 is already 1col; keep the
     checkbox row tidy */
  #page-leave-types .form-field label > span { gap: 6px; }
}

/* ─── Modal — mobile (≤600px already handled in forms.css) ──────
   Extra polish: on very narrow screens, drop the max-width so the
   modal fills the available width comfortably. */
@media (max-width: 480px) {
  .modal-backdrop { padding: 12px 8px; align-items: flex-start; }
  .modal-card {
    max-width: none;
    margin: 0;
    border-radius: 10px;
  }
  .modal-head { margin-bottom: 8px; }
  .modal-title { font-size: 15px; }
  /* Payment modal's clear button sits on the right — let it wrap to
     its own row on phones so it doesn't crowd Save/Cancel. */
  #pr-payment-modal .form-actions { flex-direction: column; align-items: stretch; gap: 8px; }
  #pr-payment-modal .form-actions #pr-pay-clear-btn {
    margin-left: 0 !important;
    margin-top: 4px;
  }
}

/* ─── Balance inputs in employees edit form ─────────────────────
   The per-type grid collapses to 1col at 480 via the form-grid rule,
   but we want the field-hint (default + used info) to stay visible. */
@media (max-width: 480px) {
  #ne-balances-container .form-field .field-hint {
    font-size: 11px;
    line-height: 1.4;
  }
}

/* ─── Leave apply form hint (available days) ────────────────────
   Make it prominent enough on mobile that users check before submitting. */
@media (max-width: 480px) {
  #apply-type-balance {
    font-size: 13px;
    margin-top: 6px;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   §E mobile sweep — additions on top of the existing layer.
   Order matters: the iOS 16px input fix sits below the existing rules
   so it wins specificity ties; component-specific tweaks come after.
   ═══════════════════════════════════════════════════════════════════ */

/* ─── iOS zoom-on-focus fix ──────────────────────────────────────
   Mobile Safari + iOS Chrome auto-zoom when the focused input has
   font-size < 16px. Bumping every form control to 16px below 768
   kills the zoom without bleeding into desktop where 13–14px is the
   design system default. Excludes the topbar search (hidden below
   768) and toggle controls. */
@media (max-width: 768px) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
  select,
  textarea {
    font-size: 16px !important;
  }
  .form-field label { font-size: 13px; }
}

/* ─── Tap targets ≥ 44px earlier (≤768) ─────────────────────────
   The existing 480-only rule misses iPad-portrait. Apply at 768. */
@media (max-width: 768px) {
  .btn,
  .btn-sm { min-height: 44px; }
  .form-field select,
  .form-field input:not([type="checkbox"]):not([type="radio"]) { min-height: 44px; }
}

/* ─── Modal: full-screen below 600px ─────────────────────────────
   forms.css centres the modal in a backdrop; on phones that wastes
   margins and crams the dialog. Below 600 we go edge-to-edge with a
   sticky head + sticky form-actions footer so cancel/save stays
   reachable while scrolling a long form. */
@media (max-width: 600px) {
  .modal-backdrop {
    padding: 0 !important;
    align-items: stretch !important;
  }
  .modal-card {
    width: 100% !important;
    max-width: 100% !important;
    min-height: 100vh;
    min-height: 100dvh;
    max-height: 100vh;
    max-height: 100dvh;
    margin: 0 !important;
    border-radius: 0 !important;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
  }
  .modal-head {
    position: sticky;
    top: 0;
    background: var(--surface);
    z-index: 5;
    padding: 14px 16px;
    padding-top: calc(env(safe-area-inset-top) + 14px);
    margin: 0 0 8px;
    border-bottom: 1px solid var(--border);
  }
  .modal-card > *:not(.modal-head) {
    padding-left: 16px;
    padding-right: 16px;
  }
  .modal-card .form-actions {
    position: sticky;
    bottom: 0;
    background: var(--surface);
    padding: 12px 16px;
    padding-bottom: calc(env(safe-area-inset-bottom) + 12px);
    margin-left: -16px;
    margin-right: -16px;
    margin-top: auto;
    border-top: 1px solid var(--border);
    z-index: 5;
  }
}

/* ─── AI chat panel: full-screen below 600px ─────────────────────
   Desktop panel is 525×806 anchored bottom-right. On phones it should
   be a full-viewport sheet so messages aren't cramped. */
@media (max-width: 600px) {
  .ai-chat-panel,
  #ai-chat-panel {
    position: fixed !important;
    inset: 0 !important;
    width: 100% !important;
    height: 100vh !important;
    height: 100dvh !important;
    max-height: 100vh !important;
    max-height: 100dvh !important;
    border-radius: 0 !important;
    z-index: 9000 !important;
  }
  /* Header clear of the notch, composer clear of the home-bar. */
  .ai-chat-head { padding-top: calc(env(safe-area-inset-top) + 12px); }
  .ai-chat-input-row { padding-bottom: calc(env(safe-area-inset-bottom) + 10px); }
  /* Scrolling the thread must not chain to the page behind it. */
  .ai-chat-messages { overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
}

/* ─── Attachment lightbox edge-to-edge on phones ─────────────── */
@media (max-width: 600px) {
  .attachment-lightbox { padding: 8px !important; }
  .attachment-lightbox-frame {
    max-width: 100% !important;
    max-height: 100vh !important;
    max-height: 100dvh !important;
    border-radius: 0 !important;
  }
  .attachment-lightbox-frame iframe {
    height: 100vh !important;
    height: 100dvh !important;
  }
  .attachment-lightbox-img,
  .attachment-lightbox-pdf { max-height: 80vh !important; max-height: 80dvh !important; }
}

/* ─── Sticky-topbar scroll margin ─────────────────────────────── */
@media (max-width: 768px) {
  .page-title,
  .card-title { scroll-margin-top: 80px; }
}

/* ─── Push settings — device list wraps on narrow screens ───── */
@media (max-width: 480px) {
  #push-devices-list li { flex-wrap: wrap; }
  #push-devices-list li > div { flex: 1 1 100%; }
  #push-devices-list li button { margin-left: auto; }
}

/* ─── Kanban → single column + status tabs on phones ─────────────
   A 4-wide board (or a 4-tall stack of near-empty columns) is poor on
   a phone. ≤640px we show ONE column at a time, picked by a tab strip
   that mirrors exactly the visible columns. The desktop rule below
   keeps the tab strip hidden; the media block (later in source) wins
   at ≤640px. */
.kanban-mobile-tabs { display: none; }

@media (max-width: 640px) {
  .kanban-mobile-tabs {
    display: flex;
    gap: 6px;
    margin: 12px 0 10px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .kanban-mobile-tabs::-webkit-scrollbar { display: none; }
  .kanban-mobile-tabs button {
    flex: 0 0 auto;
    min-height: 44px;
    padding: 0 16px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    color: var(--muted);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
  }
  .kanban-mobile-tabs button.active {
    background: var(--purple);
    color: #fff;
    border-color: var(--purple);
  }
  .kanban-mobile-tabs .kmt-count { font-size: 11px; opacity: .85; }

  /* Show only the selected column; it takes the full width. */
  .kanban-board { display: block !important; }
  .kanban-board .kanban-col {
    display: none !important;
    min-height: 0 !important;
    margin-bottom: 0 !important;
  }
  .kanban-board[data-mcol="todo"]      .kanban-col-todo,
  .kanban-board[data-mcol="progress"]  .kanban-col-progress,
  .kanban-board[data-mcol="done"]      .kanban-col-done,
  .kanban-board[data-mcol="cancelled"] .kanban-col-cancelled {
    display: block !important;
  }
}

/* ─── Interactive status pill = the touch move-affordance ────────
   Drag-to-move doesn't work on touch, so the clickable status pill is
   the only way to advance a card on a phone — it must be tappable. */
@media (max-width: 768px) {
  .kanban-card .tasks-pill:not(.no-action) {
    min-height: 34px;
    padding: 6px 14px;
    font-size: 12px;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   PER-PAGE POLISH — the last-mile fixes the page audits surfaced.
   =================================================================== */

/* Tab strips (My Tasks status filter, My Activity tabs) must never
   overflow — scroll them horizontally on one line instead of clipping
   or wrapping into a broken second row. */
@media (max-width: 640px) {
  .tasks-status-filter,
  .ma-tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .tasks-status-filter::-webkit-scrollbar,
  .ma-tabs::-webkit-scrollbar { display: none; }
  .tasks-status-filter button,
  .ma-tab { flex: 0 0 auto; white-space: nowrap; }
  /* The spacer pushes Export/Refresh off-screen on a phone — drop it
     and let the controls scroll into reach instead. */
  .ma-tab-spacer { display: none; }
}

/* My Activity custom date range: each control full-width, no cramming. */
@media (max-width: 480px) {
  .ma-custom-row { gap: 8px; }
  .ma-custom-field { flex: 1 1 100%; }
}

/* Payroll Edit-Payslip LOP row: a fixed 70px×100px input flex that
   overflowed at 375px — let it wrap. */
@media (max-width: 480px) {
  .pr-edit-lop-inputs { flex-wrap: wrap; }
}

/* Manager review KPIs: 5-across is unreadable on a phone. 2-up with a
   smaller number so values never clip. */
@media (max-width: 480px) {
  .mr-kpis { grid-template-columns: 1fr 1fr !important; gap: 8px; }
  .mr-kpi-num { font-size: 19px !important; }
  .mr-kpi { padding: 10px !important; }
}

/* Task-detail sticky header: its negative margins / top:-22px were
   tuned to the desktop floating card's padding. In the ≤600px
   full-screen sheet that mis-aligns — pin it to the real sheet top. */
@media (max-width: 600px) {
  .task-detail.compact .task-detail-header {
    top: 0;
    margin: 0 0 10px;
    border-radius: 0;
  }
}

/* Org-chart fallback tree: deep nesting (18px indent per level) pushed
   wide cards past the viewport. Cap indent + let the tree scroll
   internally so the page itself never scrolls sideways. */
@media (max-width: 480px) {
  .org-fallback-tree {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .org-fallback-tree ul { padding-left: 12px; }
  .org-fallback-card { display: flex; max-width: 100%; }
}

/* Notification-settings sticky Save bar: keep the Save/Discard buttons
   clear of the iOS home-indicator in the installed PWA. */
@media (max-width: 768px) {
  #page-notification-settings .ns-savebar {
    padding-bottom: calc(env(safe-area-inset-bottom) + 14px);
  }
}

/* ═══════════════════════════════════════════════════════════════════
   MOBILE TYPE & BUTTON SYSTEM
   The app accreted ~20 ad-hoc font-sizes (9.5/10/10.5/11/11.5/12/12.5/
   13/13.5/14/15…) and three different button text sizes (.btn 14 /
   .btn-sm 12 / .btn-xs 11) plus per-component overrides (11/11.5/12).
   On a phone that reads as noise. Snap the component roles onto one
   tight scale and make the buttons a single system. Scoped ≤768px —
   desktop is untouched. (.tbl-cards card text already normalised to
   14px in its own block above.)

   Scale:  title 22 · heading 18 · body 14 · meta 13 · label 11
   =================================================================== */
@media (max-width: 768px) {
  /* Titles / headings — a clean descending step, not 24→22→20 drift */
  .page-title {
    font-size: 22px !important;
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.25;
  }
  .page-subtitle { font-size: 13px !important; line-height: 1.45; }
  .modal-title { font-size: 18px !important; }
  .task-detail.compact h2,
  .task-detail-head h2 { font-size: 18px !important; }
  /* Card eyebrow stays a small-caps label — just consistent */
  .card-title {
    font-size: 11px !important;
    font-weight: 700;
    letter-spacing: 0.08em;
  }

  /* Captions / hints — collapse the 9.5–11.5 soup to one readable size */
  .field-hint { font-size: 12px !important; line-height: 1.5; }
  /* Badges were 10px at ≤480 — below comfortable reading */
  .badge { font-size: 11px !important; padding: 3px 10px; }
  /* Scrolled (non-card) tables: a readable floor */
  .tbl-wrap table { font-size: 13px; }

  /* Buttons → ONE system. !important deliberately overrides the
     scattered per-component sizes (.task-detail-actions .btn:12,
     .tasks-inline-row .btn:11.5, .ma-custom-presets .btn:11, …) so
     every button on a phone reads at one weight/size. Height is
     already ≥44px from the touch-target block. */
  .btn,
  .btn-sm { font-size: 14px !important; font-weight: 600; }
  .btn-xs { font-size: 13px !important; font-weight: 600; }
}
