/* ============================================================
   SIM-SG SACCO — RESPONSIVE APP UI
   Mobile-first responsive overhaul for a native-app feel.
   Tables (dynamic DB data) collapse into stacked cards on small
   screens, buttons get proper tap targets, the topbar becomes a
   clean app header, modals become bottom sheets, and nothing
   overflows the viewport.

   TYPOGRAPHY NOTE: sizes were tuned down ~10% from the first
   mobile pass — the previous scale was too large, which pushed
   buttons/labels off-screen and made cards feel cramped. Inputs
   stay at 16px minimum because iOS Safari auto-zooms the page
   when it focuses a smaller field.
   ============================================================ */

/* ============================================================
   1. GLOBAL RESETS — apply at every breakpoint
   ============================================================ */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
}

*, *::before, *::after {
  box-sizing: border-box;
}

/* Never let anything spill past the viewport */
body, .app-layout, .main, .page-content,
.shell, .content, .doc-section {
  max-width: 100vw;
  overflow-x: hidden;
}

img, svg, video, iframe {
  max-width: 100%;
  height: auto;
}

/* Touch-friendly interactive elements everywhere */
button, a, [role="button"], .tab, .nav-item {
  touch-action: manipulation;
}

/* Mobile bottom tab bar is hidden by default (shown on small screens) */
.mobile-tabbar { display: none; }

/* ============================================================
   2. ROOT-LEVEL FIXES (override main.css so content can shrink)
   ============================================================ */

.stat-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
}
.grid-2  { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) !important; }
.grid-3  { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
.two-col { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) !important; }

.grid-2 > *, .grid-3 > *, .two-col > * {
  min-width: 0 !important;
  max-width: 100% !important;
}

/* Stat cards must never overflow */
.stat-card  { min-width: 0 !important; overflow: hidden; }
.stat-card-top { flex-wrap: wrap !important; gap: 8px; }
.stat-value { word-break: break-word; }

/* Buttons keep their label on ONE line. `word-break: break-word` used to
   squeeze table buttons until the word split mid-label ("acce" / "pt");
   nowrap + no word-breaking means a tight row wraps the whole button onto
   the next line instead of breaking the text inside it. */
.btn {
  white-space: nowrap !important;
  word-break: normal !important;
  overflow-wrap: normal !important;
  hyphens: none !important;
}
/* Badges may wrap between words, but never inside one. */
.badge {
  white-space: normal !important;
  word-break: normal !important;
  overflow-wrap: break-word;
  hyphens: none !important;
}

/* Button groups inside a table cell stack instead of being crushed by the
   fixed column width. (:has() degrades quietly on old browsers — the pages
   also set flex-wrap inline where it matters.) */
.table-wrap table td > div:has(> .btn),
.table-wrap table td > div:has(> button) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}
.table-wrap table td .btn { flex: 0 0 auto; }

/* Member cells truncate long names */
.member-cell { min-width: 0; overflow: hidden; }
.member-cell > span,
.member-cell .member-cell-info .name {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 100%; display: block;
}

/* Tables never force a min-width */
table { table-layout: fixed !important; }
.table-wrap table { min-width: unset !important; width: 100% !important; }

/* Notice strip wraps */
.notice-strip { flex-wrap: wrap !important; max-width: 100%; }

/* Detail rows (label + value) must wrap instead of overflowing — long
   values (names, amounts, chips) were being clipped or pushing the row
   wider than the card on narrow screens. */
.detail-row { flex-wrap: wrap; gap: 4px 10px; }
.detail-row > span { min-width: 0; overflow-wrap: anywhere; }

/* ============================================================
   3. TABLET — 769px to 1024px
   ============================================================ */
@media (max-width: 1024px) and (min-width: 901px) {
  .stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; gap: 14px !important; }
  .grid-2, .grid-3 { grid-template-columns: 1fr !important; }
  .form-grid-2, .loan-form-grid { grid-template-columns: 1fr !important; }
  .two-col   { grid-template-columns: 1fr 1fr !important; }
  .role-grid { grid-template-columns: 1fr 1fr !important; }
  .three-col, .four-col, .col2, .col3, .col4 { grid-template-columns: minmax(0,1fr) !important; }
  .stat-value { font-size: 20px !important; }
  .stat-label { font-size: 12px !important; }
  .page-content { padding: 20px 24px !important; }
}

/* ============================================================
   4. MOBILE APP — up to 900px
   Native-app typography & touch targets, tuned a notch smaller so
   more content fits and nothing gets pushed off-screen.
   ============================================================ */
@media (max-width: 900px) {
  body { font-size: 15.5px; }

  /* ---------- Layout ---------- */
  .app-layout { display: block; }

  /* Sidebar becomes a slide-in drawer */
  .sidebar {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: 280px;
    max-width: 86vw;
    transform: translateX(-100%);
    transition: transform .25s ease;
    z-index: 300;
    box-shadow: 4px 0 24px rgba(0,0,0,.35);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  .sidebar.open { transform: translateX(0); }
  .sidebar .nav-item { font-size: 14.5px; padding: 13px 18px; gap: 11px; }
  .sidebar .nav-group-label { font-size: 11px; padding: 18px 18px 5px; }
  .sidebar-brand-name { font-size: 14.5px; }
  .sidebar-user-name { font-size: 13.5px; }
  .sidebar-user-role { font-size: 11.5px; }
  .btn-logout { font-size: 13.5px; padding: 10px 0; }

  .sidebar-overlay {
    display: none;
    position: fixed; inset: 0;
    background: rgba(15,23,42,.55);
    z-index: 299;
  }
  .sidebar-overlay.active { display: block; }

  .main { margin-left: 0 !important; width: 100% !important; }
  .page-content {
    padding: 16px !important;
    /* the same variable as the comfort pass below, so the two rules can never
       disagree about how far the bottom menu reaches */
    padding-bottom: var(--tabbar-clearance, calc(96px + env(safe-area-inset-bottom, 0px))) !important;
  }

  /* ---------- Mobile bottom tab bar (native-app nav) ---------- */
  .mobile-tabbar {
    display: flex;
    flex-wrap: nowrap;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 250;
    background: var(--surface);
    border-top: 1px solid var(--border);
    box-shadow: 0 -2px 18px rgba(15,23,42,.1);
    padding-bottom: env(safe-area-inset-bottom, 0);
  }
  .tabbar-item {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-height: 56px;
    padding: 7px 4px 9px;
    background: none; border: none;
    color: var(--text-muted);
    font-family: inherit;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .01em;
    cursor: pointer;
  }
  .tabbar-item > span {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .tabbar-item svg { width: 21px; height: 21px; color: currentColor; }
  .tabbar-item:active { background: var(--surface-2); }
  .tabbar-item.active { color: var(--blue); }

  /* ---------- Topbar / app header ---------- */
  .topbar {
    height: 58px;
    padding: 0 12px;
    box-shadow: 0 1px 8px rgba(15,23,42,.1);
    justify-content: flex-start;
    gap: 6px;
  }
  .topbar-title {
    font-size: 19px;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1 1 auto;
    min-width: 0;
  }
  .topbar-sub   { display: none; }
  .topbar-date  { display: none; }
  .topbar-right { margin-left: auto; flex-shrink: 0; gap: 8px; }

  /* Hamburger — order it before the title */
  .topbar-left { order: -1; flex-shrink: 0; }
  .hamburger {
    display: flex !important;
    align-items: center; justify-content: center;
    width: 42px; height: 42px;
    background: none; border: none; cursor: pointer;
    color: var(--text-primary);
    margin-right: 2px; flex-shrink: 0;
    border-radius: 10px;
  }
  .hamburger:active { background: var(--surface-2); }
  .hamburger svg { width: 22px; height: 22px; }

  .notif-btn { padding: 8px; flex-shrink: 0; }
  .notif-btn svg { width: 21px; height: 21px; }
  .notif-badge { font-size: 9px; width: 15px; height: 15px; top: 1px; right: 1px; }

  /* ---------- Stats grid — single column, stacked downward ---------- */
  .stat-grid { grid-template-columns: minmax(0, 1fr) !important; gap: 12px !important; }
  .stat-card { padding: 15px 16px !important; border-radius: 14px !important; }
  .stat-card-top { flex-wrap: wrap !important; gap: 10px !important; margin-bottom: 12px; }
  /* sizes live in the mobile type pass at the end of this file */
  .stat-label { margin-bottom: 4px; }

  /* ---------- Grids ---------- */
  .grid-2, .grid-3, .two-col, .three-col,
  .four-col, .col2, .col3, .col4,
  .form-grid-2, .loan-form-grid, .role-grid {
    grid-template-columns: minmax(0, 1fr) !important;
    gap: 14px !important;
  }
  .grid-2 > *, .grid-3 > * { min-width: 0 !important; max-width: 100% !important; overflow: hidden; }

  /* ---------- Panels ---------- */
  .panel { margin-bottom: 18px; border-radius: 14px !important; overflow: hidden; }
  .panel-header { padding: 14px 16px !important; flex-wrap: wrap; gap: 8px; }
  .panel-title  { font-size: 16.5px !important; font-weight: 600; }
  .panel-footer { padding: 13px 16px !important; }

  .link-subtle { font-size: 13.5px !important; }

  /* ---------- Tabs ---------- */
  .tab-row {
    overflow-x: auto !important;
    flex-wrap: nowrap !important;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 1px;
    margin-inline: -16px;
    padding-inline: 16px;
  }
  .tab {
    white-space: nowrap !important;
    padding: 11px 14px !important;
    font-size: 14.5px !important;
    min-height: 44px;
  }

  /* ---------- Forms ---------- */
  .form-control {
    font-size: 16px !important; /* 16px is the floor: iOS auto-zooms below it */
    padding: 12px 13px !important;
    border-radius: 11px !important;
    min-height: 46px;
    width: 100%;
  }
  select.form-control { font-size: 16px !important; }
  textarea.form-control { min-height: 88px; }
  .form-label { font-size: 13.5px !important; margin-bottom: 6px; }
  .form-hint  { font-size: 12.5px !important; margin-top: 5px; line-height: 1.45; }
  .form-error { font-size: 12.5px !important; margin-top: 5px; line-height: 1.45; }
  .form-group { margin-bottom: 18px; }
  .form-info  { font-size: 13.5px !important; padding: 12px 13px !important; line-height: 1.5; }
  .form-grid-2 > * { min-width: 0; }

  /* ---------- Buttons — full app-sized tap targets ---------- */
  .btn {
    min-height: 48px;
    padding: 12px 18px !important;
    font-size: 15.5px !important;
    font-weight: 600;
    border-radius: 11px !important;
    justify-content: center;
    gap: 7px;
  }
  .btn-sm { min-height: 42px; padding: 9px 14px !important; font-size: 14px !important; }
  .btn:active { transform: scale(.98); }
  .btn svg { width: 16px !important; height: 16px !important; }
  .btn.btn-icon { width: 42px; height: 42px; padding: 0 !important; }

  /* ---------- Modal footers stack full-width ---------- */
  .modal-footer { flex-direction: column; }
  .modal-footer .btn { width: 100%; }

  /* ---------- Settings / danger zone ---------- */
  .settings-section { padding: 15px !important; }
  .danger-zone      { padding: 15px !important; }

  /* ---------- Steps (loan wizard) ---------- */
  .step-row { flex-wrap: wrap !important; gap: 6px !important; justify-content: center; margin-bottom: 18px; }
  .step-line { display: none !important; }
  .step      { font-size: 12.5px !important; gap: 7px; }
  .step-num  { width: 25px !important; height: 25px !important; font-size: 11.5px !important; }

  .calc-result { padding: 13px 15px !important; max-width: 100%; box-sizing: border-box; border-radius: 11px !important; }
  .calc-row    { font-size: 13.5px !important; flex-wrap: wrap; gap: 6px; margin-bottom: 7px; }
  .calc-label  { font-size: 13.5px; }
  .calc-value  { font-size: 13.5px; }

  /* Loan terms block (shared admin/member component) */
  .loan-terms { padding: 13px 14px !important; border-radius: 11px !important; }
  .loan-terms-title { font-size: 10.5px !important; }
  .loan-terms-grid { grid-template-columns: minmax(0, 1fr) !important; gap: 2px !important; }
  .loan-terms-row { font-size: 13.5px !important; }
  .loan-terms-total { font-size: 14px !important; }
  .loan-terms-formula { font-size: 12px !important; }

  .guarantor-option { padding: 12px 13px !important; gap: 11px !important; border-radius: 11px !important; }
  .guarantor-option input { width: 20px; height: 20px; }

  /* ---------- Notice strip ---------- */
  .notice-strip {
    font-size: 13.5px !important;
    padding: 12px 13px !important;
    flex-wrap: wrap !important;
    gap: 8px !important;
    max-width: 100% !important;
    box-sizing: border-box;
    border-radius: 12px !important;
    line-height: 1.5;
  }

  /* ---------- Profile hero ---------- */
  .profile-hero {
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: 12px !important;
    padding: 18px !important;
  }
  .field-block { padding: 10px 0 !important; }
  .field-value { font-size: 15.5px !important; }

  /* ---------- Guarantors ---------- */
  .guarantor-chip {
    display: inline-flex !important;
    margin: 3px !important;
    font-size: 12px !important;
    padding: 4px 9px !important;
    max-width: 100%;
    overflow-wrap: anywhere;
  }
  .member-cell { gap: 9px !important; max-width: 100%; }
  .member-cell > span, .member-cell .member-cell-info .name {
    font-size: 15px !important;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    max-width: 170px; display: block;
  }
  .member-cell-info .id { font-size: 11.5px !important; }
  .badge { font-size: 12px !important; padding: 5px 10px !important; }
  .detail-row   { font-size: 14.5px !important; padding: 9px 0 !important; }
  .detail-label { font-size: 12.5px !important; }

  /* ---------- Documentation page ---------- */
  .shell   { display: block !important; }
  .content { padding: 16px !important; max-width: 100% !important; width: 100% !important; }
  .doc-section { padding: 18px 16px !important; margin-bottom: 16px !important; }
  .two-col, .role-grid { grid-template-columns: 1fr !important; gap: 14px !important; }
  .status-table {
    display: block; overflow-x: auto;
    -webkit-overflow-scrolling: touch; white-space: nowrap;
    font-size: 13.5px !important;
  }
  .steps .step { padding-bottom: 16px; }
  .step-desc   { font-size: 13.5px !important; }
  .info-card   { padding: 13px 14px !important; }
  .info-card-title { font-size: 13.5px !important; }
  .info-card-desc  { font-size: 12.5px !important; }
  .summary-box p  { font-size: 13.5px !important; line-height: 1.65 !important; }
  .topbar .back-btn { font-size: 13px !important; padding: 8px 12px !important; min-height: 40px; }

  /* ---------- Fix hard-coded tiny inline fonts ----------
     Many page templates set font-size inline (10–13px). Inline styles
     beat ordinary CSS, so they stayed tiny no matter what. Nudge them
     up on mobile so nothing needs zooming (kept modest so cards do not
     overflow again). */
  *[style*="font-size:10px"] { font-size: 12px !important; line-height: 1.4; }
  *[style*="font-size:11px"] { font-size: 12.5px !important; line-height: 1.4; }
  *[style*="font-size:12px"] { font-size: 13.5px !important; line-height: 1.45; }
  *[style*="font-size:13px"] { font-size: 14px !important; line-height: 1.45; }

  /* ---------- Collapse the huge empty-state paddings ---------- */
  .panel-body[style*="text-align:center"][style*="padding:30px"],
  .panel-body[style*="text-align:center"][style*="padding:40px"],
  .panel-body[style*="text-align:center"][style*="padding:48px"],
  .panel-body[style*="text-align:center"][style*="padding:56px"],
  .panel-body[style*="text-align:center"][style*="padding:60px"],
  div[style*="text-align:center"][style*="padding:30px"],
  div[style*="text-align:center"][style*="padding:40px"],
  div[style*="text-align:center"][style*="padding:48px"],
  div[style*="text-align:center"][style*="padding:56px"],
  div[style*="text-align:center"][style*="padding:60px"] {
    padding: 20px 14px !important;
  }

  /* ---------- Safety net ---------- */
  .page-content { word-wrap: break-word; overflow-wrap: break-word; }
  .page-content * { max-width: 100%; }
}

/* ============================================================
   5. DYNAMIC DATA TABLES → STACKED CARDS (small screens)
   The JS helper `labelTables()` adds data-label + the .data-table
   class. On phones each row becomes its own card so every column
   stays visible with no horizontal scrolling.
   ============================================================ */
@media (max-width: 900px) {
  .table-wrap { overflow: visible; }

  .table-wrap table.data-table,
  .table-wrap table.data-table thead,
  .table-wrap table.data-table tbody,
  .table-wrap table.data-table tr,
  .table-wrap table.data-table td {
    display: block;
    width: 100%;
    box-sizing: border-box;
  }

  .table-wrap table.data-table thead { display: none; }

  .table-wrap table.data-table tbody tr {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 13px;
    box-shadow: var(--shadow);
    margin-bottom: 12px;
    overflow: hidden;
  }

  .table-wrap table.data-table td {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 15px;
    min-height: 48px;
    border-bottom: 1px solid var(--border);
    font-size: 15px;
    text-align: right;
    overflow-wrap: break-word;
    word-break: normal;
  }
  /* Buttons inside a card row keep their label intact */
  .table-wrap table.data-table td .btn { white-space: nowrap !important; }
  .table-wrap table.data-table td:last-child { border-bottom: none; }

  /* Column label on the left of every cell */
  .table-wrap table.data-table td::before {
    content: attr(data-label);
    flex-shrink: 0;
    max-width: 42%;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-muted);
    text-align: left;
  }

  /* Empty-state / colspan rows are full-width centered */
  .table-wrap table.data-table td[data-colspan] {
    display: block;
    text-align: center;
    padding: 16px 14px;
  }
  .table-wrap table.data-table td[data-colspan]::before { content: none; }
  .table-wrap table.data-table td[data-colspan] .empty-state { margin: 0 auto; }

  /* Keep member avatar+name compact inside the card */
  .table-wrap table.data-table td .member-cell {
    justify-content: flex-end;
    min-width: 0;
  }
  .table-wrap table.data-table td .member-cell-info { min-width: 0; }

  /* Action buttons sit right-aligned together */
  .table-wrap table.data-table td[data-label="Actions"],
  .table-wrap table.data-table td[data-label="Action"] {
    justify-content: flex-end;
    flex-wrap: wrap;
  }
  .table-wrap table.data-table td[data-label="Actions"] .btn,
  .table-wrap table.data-table td[data-label="Actions"] button,
  .table-wrap table.data-table td[data-label="Action"] .btn,
  .table-wrap table.data-table td[data-label="Action"] button {
    flex-shrink: 0;
  }
}

/* ============================================================
   6. MODALS → BOTTOM SHEETS (small screens)
   Modals are lifted above the fixed bottom tab bar (z-index 250),
   which used to cover the sheet's footer buttons.
   ============================================================ */
@media (max-width: 900px) {
  .modal-overlay { z-index: 400 !important; }
  .toast         { z-index: 600 !important; bottom: calc(80px + env(safe-area-inset-bottom, 0px)) !important; left: 16px; right: 16px; text-align: center; }
}

@media (max-width: 600px) {
  .modal-overlay {
    align-items: flex-end !important;
    padding: 0 !important;
  }
  .modal {
    border-radius: 20px 20px 0 0 !important;
    max-height: calc(100% - 8px) !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch;
    width: 100% !important;
    max-width: 100% !important;
    padding: 20px 18px calc(28px + env(safe-area-inset-bottom, 0px)) !important;
  }
  /* Drag handle */
  .modal::before {
    content: '';
    display: block;
    width: 48px; height: 4px;
    border-radius: 3px;
    background: var(--border);
    margin: 0 auto 16px;
    flex-shrink: 0;
  }
  .modal-title { font-size: 19px !important; }
  .modal-sub   { font-size: 13.5px !important; margin-bottom: 16px !important; }
}

/* ============================================================
   7. VERY SMALL PHONES — up to 400px
   ============================================================ */
@media (max-width: 400px) {
  body          { font-size: 15px; }
  .stat-grid    { grid-template-columns: 1fr !important; }
  .page-content { padding: 14px !important; }
  .topbar-title { font-size: 17.5px !important; }
  .panel-header { padding: 13px 14px !important; }
  .stat-value   { font-size: 24px !important; }
  .btn { min-height: 46px; }
  .tabbar-item { font-size: 10.5px; }
  .tabbar-item svg { width: 20px; height: 20px; }

  .content     { padding: 14px !important; }
  .doc-section { padding: 15px 14px !important; }
}

/* ============================================================
   8. DESKTOP — hide mobile-only chrome
   ============================================================ */
@media (min-width: 901px) {
  .hamburger       { display: none !important; }
  .sidebar-overlay { display: none !important; }
}

/* ============================================================
   9. PRINT
   ============================================================ */
@media print {
  .sidebar, .topbar, .hamburger,
  .sidebar-overlay, .btn, .notif-btn,
  .btn-logout, .back-btn, .mobile-tabbar { display: none !important; }
  .main         { margin-left: 0 !important; }
  .page-content { padding: 0 !important; }
  .panel        { box-shadow: none !important; border: 1px solid #ccc !important; }
  .table-wrap table.data-table tbody tr {
    border: none; box-shadow: none; break-inside: avoid;
  }
}


/* ============================================================
   9. SELF-SIZING STAT GRIDS
   .stat-grid-auto opts a panel out of the fixed 4/2/1 column rules
   so a row with 3 or 5 cards (Reports: Money In / Money Out) fills
   the width instead of leaving a hole.
   ============================================================ */
.stat-grid.stat-grid-auto {
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)) !important;
}
@media (max-width: 1024px) and (min-width: 901px) {
  .stat-grid.stat-grid-auto { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
}
@media (max-width: 900px) {
  .stat-grid.stat-grid-auto { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
}
@media (max-width: 600px) {
  .stat-grid.stat-grid-auto { grid-template-columns: minmax(0, 1fr) !important; }
}


/* ============================================================
   7. MOBILE COMFORT PASS
   ---------------------------------------------------------------
   Three things the earlier mobile rules got wrong, addressed together:
   the fixed bottom tab bar covering page content, modals/dropdowns
   fighting it for the same strip of screen, and a type scale that was
   simply too large for a phone. Sizes here are ~12-15% under the
   desktop scale, and inputs stay at 16px on phones because iOS Safari
   zooms the whole page when a focused field is smaller than that.
   ============================================================ */

/* -- nothing hides behind the bottom bar --------------------- */
@media (max-width: 900px) {
  /* js/utils.js measures the real bar height; this is what applies before that
     and whenever the bar is not on screen (a modal owns the strip, or desktop).
     It is deliberately a little more than the bar itself: content that flows to
     the end of a page needs to stop above the menu, not under it. */
  :root { --tabbar-clearance: calc(96px + env(safe-area-inset-bottom, 0px)); }

  .page-content {
    padding: 14px 12px !important;
    padding-bottom: var(--tabbar-clearance, calc(96px + env(safe-area-inset-bottom, 0px))) !important;
    scroll-padding-bottom: calc(var(--tabbar-clearance, calc(96px + env(safe-area-inset-bottom, 0px))) + 16px);
  }
  /* the document itself scrolls on several pages, and an anchor/focus jump
     lands at the very bottom edge — give the same clearance there */
  html { scroll-padding-bottom: calc(var(--tabbar-clearance, calc(96px + env(safe-area-inset-bottom, 0px))) + 12px); }
  /* A modal or the open notifications sheet owns the screen; the tab bar is
     the one thing that must get out of its way. Kept as separate rules: a
     browser without :has() drops the whole selector list it appears in, and
     the class-based fallbacks must survive that. */
  body.has-modal .mobile-tabbar,
  body.notif-open .mobile-tabbar { display: none !important; }
  body:has(.modal-overlay.open) .mobile-tabbar,
  body:has(.modal.show) .mobile-tabbar,
  body:has(.modal-overlay[style*="display: flex"]) .mobile-tabbar,
  body:has(.modal[style*="display: flex"]) .mobile-tabbar { display: none !important; }

  /* A dialog obeys the same law as the page: it never runs into the strip the
     bottom menu occupies. While the menu is on screen the dialog box is laid
     out above it; when the menu has stepped aside for the dialog (the rules
     just above) the box simply gets a small gap. Heights are capped against
     the overlay itself rather than vh, because vh on a phone is the tallest the
     viewport ever gets, which is what pushed a stretched modal's footer off the
     screen. One block, applying to every page that uses .modal-overlay. */
  .modal-overlay {
    padding-bottom: calc(var(--tabbar-clearance, calc(96px + env(safe-area-inset-bottom, 0px))) + 8px) !important;
  }
  body.has-modal .modal-overlay,
  body:has(.modal-overlay.open) .modal-overlay,
  body:has(.modal.show) .modal-overlay { padding-bottom: 14px !important; }
  .modal { max-height: calc(100% - 16px) !important; }

  @media (max-width: 600px) {
    /* the bottom sheet is deliberately flush with the bottom edge, so it keeps
       the overlay's zero padding; the safe-area padding inside .modal is what
       lifts its buttons above the home indicator */
    .modal-overlay { padding-bottom: 0 !important; }
  }

  .toast, #simsg-toast {
    /* the clearance already contains the safe area, so it is not added again */
    bottom: calc(var(--tabbar-clearance, 96px) + 6px) !important;
  }

  /* Tap targets: the row actions have to be usable with a thumb, and they
     carry no hover state on touch, so colour them up rather than dimming. */
  .icon-actions { gap: 8px !important; }
  .icon-btn { width: 40px !important; height: 40px !important; border-radius: 9px !important; }
  .icon-btn svg { width: 20px !important; height: 20px !important; }
  .table-wrap table.data-table td[data-label="Actions"] .icon-actions,
  .table-wrap table.data-table td[data-label="Action"] .icon-actions {
    justify-content: flex-end; width: 100%;
  }

  /* -- notifications: a sheet with its own scrolling list ---- */
  #notif-panel, .notif-panel {
    position: fixed !important;
    top: 56px !important;
    left: 10px !important;
    right: 10px !important;
    width: auto !important;
    max-width: none !important;
    display: none;
    flex-direction: column !important;
    overflow: hidden !important;
    border-radius: 14px !important;
    box-shadow: 0 14px 34px rgba(15,23,42,.24) !important;
    /* stops above the tab bar so the last message is reachable */
    max-height: calc(100vh - 56px - var(--tabbar-clearance, 96px) - 12px) !important;
    z-index: 900 !important;
  }
  #notif-panel > div:first-child {
    flex: 0 0 auto;
    font-size: 13px !important; padding: 11px 14px !important;
  }
  #notif-panel .notif-list, #notif-list {
    flex: 1 1 auto; min-height: 0;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    touch-action: pan-y;
  }
  /* While the sheet is open the page behind must not scroll - that was the
     "it scrolled the table, not the messages" complaint. */
  body.notif-open { overflow: hidden; }
  #notif-list > div { padding: 10px 14px !important; }
  #notif-list > div > div:first-child { font-size: 12.5px !important; line-height: 1.45 !important; }
  #notif-list > div > div:last-child  { font-size: 10.5px !important; }
}

/* -- type scale ---------------------------------------------- */
@media (max-width: 900px) {
  body { font-size: 13.5px; }
  .topbar { height: 52px; }
  .topbar-title { font-size: 16px !important; }
  .sidebar { top: 0; }

  .stat-label { font-size: 11px !important; }
  .stat-value { font-size: 20px !important; }
  .stat-value-prefix { font-size: 11px !important; }
  .stat-icon { width: 34px !important; height: 34px !important; border-radius: 10px !important; }
  .stat-icon svg { width: 16px !important; height: 16px !important; }
  .stat-trend, .stat-sub { font-size: 10.5px !important; }

  .table-wrap table.data-table td { font-size: 12.5px !important; padding: 9px 12px !important; min-height: 42px !important; }
  .table-wrap table.data-table td::before { font-size: 10px !important; max-width: 38%; }
  .table-wrap table.data-table tbody tr { border-radius: 11px !important; margin-bottom: 9px !important; }
  .table-wrap table:not(.data-table) th,
  .table-wrap table:not(.data-table) td { font-size: 11.5px !important; padding: 8px 9px !important; }

  .card { padding: 14px !important; border-radius: 12px !important; }
  .badge { font-size: 9.5px !important; padding: 2px 7px !important; }
  .btn { font-size: 11px !important; padding: 6px 11px !important; }
  .btn-sm { font-size: 10.5px !important; padding: 5px 9px !important; }
  .btn svg { width: 14px !important; height: 14px !important; }
  .tab { font-size: 11.5px !important; padding: 8px 11px !important; }
  .form-label { font-size: 11px !important; }
  .form-control { font-size: 14px !important; padding: 7px 10px !important; }
  .hint, .field-error, .form-hint { font-size: 10.5px !important; }
  .notice-strip { font-size: 11px !important; padding: 8px 11px !important; }
  .empty-state { font-size: 12px !important; padding: 26px 16px !important; }
  .nav-item { font-size: 13px !important; padding: 11px 16px !important; }
  .tabbar-item { font-size: 10px !important; min-height: 50px !important; }
  .tabbar-item svg { width: 19px !important; height: 19px !important; }

  /* cluster / payment rows in the contributions view */
  .cluster-header { padding: 11px 13px !important; font-size: 12px !important; }
  .cluster-header > div { font-size: 12px !important; }
  .payment-row { padding: 9px 13px !important; font-size: 11.5px !important; }
  .payment-row > div { font-size: 11.5px !important; }
  .alloc-row { font-size: 11px !important; padding: 6px 9px !important; }
  .stat-pill { font-size: 10px !important; padding: 2px 7px !important; }
  .expand-btn { font-size: 10.5px !important; }
  .entry-badge { font-size: 9.5px !important; }

  /* modals as bottom sheets */
  .modal { padding: 16px 14px !important; border-radius: 14px !important; }
  .modal-title { font-size: 14px !important; }
  .modal-sub { font-size: 11px !important; margin-bottom: 12px !important; }
  .modal-footer { padding: 12px 14px !important; margin: 16px -14px -14px !important; gap: 8px !important; }
  .seg { font-size: 11.5px !important; }
  .pay-live { font-size: 11.5px !important; padding: 9px 11px !important; }
}

@media (max-width: 600px) {
  .page-content { padding: 12px 10px !important; padding-bottom: var(--tabbar-clearance, calc(96px + env(safe-area-inset-bottom, 0px))) !important; }
  /* a panel ending the page has its own padding; make sure the last row of
     buttons inside it is not the thing sitting under the menu */
  .page-content > .panel:last-child,
  .page-content > .panel-body:last-child { margin-bottom: 8px; }
  /* same for a list that scrolls inside a modal (the deleted-data manager): its
     own box has to leave room for the last row's Restore / Purge buttons */
  #purge-manager-content > div { padding-bottom: 10px; scroll-padding-bottom: 10px; }
  .stat-grid { gap: 9px !important; }
  .stat-card { padding: 12px 13px !important; }
  .stat-value { font-size: 18.5px !important; }
  .form-control { font-size: 16px !important; }  /* iOS refuses to stay un-zoomed below this */
  .modal { max-height: calc(100% - 8px) !important; }  /* never vh: the footer has to stay reachable */
  .modal, .modal-footer { padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px)) !important; }
}

@media (max-width: 400px) {
  .stat-value { font-size: 17px !important; }
  .table-wrap table.data-table td { font-size: 12px !important; }
}

/* ============================================================
   9. BULK SELECTION + MEMBER CELL — MOBILE
   The tick box becomes a tap-friendly strip at the top of each card; the
   fixed desktop table layout is released so nothing scrolls sideways.
   ============================================================ */
@media (max-width: 900px) {
  .members-table { table-layout: auto; min-width: 0; }
  .members-table td { overflow: visible; }
  .member-cell { cursor: default; }

  .bulk-bar {
    position: sticky; bottom: calc(var(--tabbar-clearance, 72px) + 8px); z-index: 40;
    margin-bottom: 12px;
  }
  .bulk-actions { margin-left: 0; width: 100%; }
  .bulk-actions .btn { flex: 1 1 auto; justify-content: center; }

  .table-wrap table.data-table td.cell-check {
    justify-content: flex-start;
    min-height: 0; padding: 9px 15px;
    border-bottom: 1px solid var(--border);
  }
  .table-wrap table.data-table td.cell-check::before { content: none; }
  .table-wrap table.data-table td.cell-check input[type="checkbox"] { width: 20px; height: 20px; opacity: 1; }
  .members-table tbody tr, .meetings-table tbody tr, .fines-table tbody tr { cursor: default; }
  /* The fines table is not fixed-layout, so it needs no release here — but its
     tick column still behaves like the other two: a tap strip at the top of a card. */
  .fines-table td.cell-check { padding-top: 9px; padding-bottom: 9px; }
}

/* ============================================================
   10. PENDING / TOOLTIP CHROME — MOBILE
   A tap has to work where a hover cannot, and the little type a member reads
   while waiting for approval must stay legible without eating the screen.
   ============================================================ */
@media (max-width: 768px) {
  .sim-tip::after {
    font-size: 11px;
    max-width: min(250px, calc(100vw - 28px));
    padding: 7px 9px;
    overflow-wrap: anywhere;
  }
  .state-chip { font-size: 9.5px; padding: 2px 7px; }
  .why-pending { font-size: 11.5px; padding: 8px 10px; gap: 7px; }
  .notif-why { font-size: 10.5px; }
  /* the bell's "n awaiting approval" pill shares a tight header row */
  #notif-panel > div:first-child { flex-wrap: wrap; }
  .notif-wait-pill { font-size: 9.5px; }
}
