/* =========================================================================
   BAST SMS — Design System v2
   Direction: modern SaaS admin — near-black slate sidebar, one confident
   indigo accent, geometric display face (Manrope) for headings/brand and
   Inter for body copy, JetBrains Mono for figures (fees, %, IDs) so data
   stays scannable in dense tables.
   ========================================================================= */

/* Google Fonts are now loaded via <link rel="preconnect"> + <link rel="stylesheet">
   in header.php / login.php <head>, instead of @import here. @import blocks
   the browser from starting the font download until this whole CSS file is
   parsed, adding an avoidable round-trip before text can render. */

:root{
  /* Slate / near-black family (sidebar, headers) */
  --ink-900:#0A0F1C;
  --ink-800:#111A2E;
  --ink-700:#182543;
  --ink-600:#22335C;

  /* Indigo accent — the single signature color */
  --accent-600:#3452D9;
  --accent-500:#4C6EF5;
  --accent-400:#7C97FF;
  --accent-100:#EAEFFF;

  /* Paper / neutrals */
  --paper:#F4F6FB;
  --paper-card:#FFFFFF;
  --line:#E4E8F1;
  --slate-700:#333B54;
  --slate-500:#6B7290;
  --slate-300:#9AA1BD;

  /* Status */
  --ok:#178A5A;
  --ok-bg:#E6F6EE;
  --bad:#D8433C;
  --bad-bg:#FBEAE9;
  --warn:#C1780C;
  --warn-bg:#FCF1DE;
  --info:#2857C7;
  --info-bg:#EAF0FD;

  --radius-lg:16px;
  --radius-md:12px;
  --radius-sm:9px;
  --shadow-card:0 2px 10px rgba(10,15,28,0.06), 0 1px 2px rgba(10,15,28,0.05);
  --shadow-card-hover:0 12px 26px rgba(10,15,28,0.10);
  --font-display:'Manrope', 'Inter', sans-serif;
  --font-body:'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono:'JetBrains Mono', SFMono-Regular, Menlo, monospace;
}

html, body{
  max-width: 100%;
  overflow-x: hidden;
}

body{
  background: var(--paper) !important;
  font-family: var(--font-body);
  color: var(--slate-700);
  -webkit-font-smoothing: antialiased;
}

h1,h2,h3,h4,h5,h6, .card-title{
  font-family: var(--font-display);
  color: var(--ink-900);
  font-weight: 700;
  letter-spacing: -0.015em;
}

h2{ position:relative; padding-bottom:.6rem; margin-bottom:1.5rem !important; font-weight:800; }
h2::after{
  content:"";
  position:absolute; left:0; bottom:0;
  width:44px; height:4px; border-radius:4px;
  background: var(--accent-500);
}

a{ color: var(--accent-600); }
a:hover{ color: var(--accent-500); }

::selection{ background: var(--accent-100); color: var(--ink-900); }

.card-kpi h3, .card-kpi h4, .fw-mono, .kpi-number, table td.num, table th.num{
  font-family: var(--font-mono);
}

/* -------------------------------------------------------------------------
   SIDEBAR — near-black slate, one accent, real hierarchy
   ------------------------------------------------------------------------- */
.sidebar, .offcanvas.d-md-none{
  background: #FFFFFF !important;
  border-right: 1px solid var(--line);
}

.sidebar-brand{
  padding: 1.7rem 1.35rem !important;
  border-bottom: 1px solid var(--line) !important;
}
.logo-badge{
  width: 46px !important; height: 46px !important;
  border-radius: 12px !important;
  background: linear-gradient(135deg, var(--accent-500), var(--accent-600)) !important;
  box-shadow: 0 4px 14px rgba(76,110,245,0.30);
  display: flex !important; align-items: center !important; justify-content: center !important;
  flex-shrink: 0;
  padding: 6px;
  position: relative;
}
.logo-badge-img{
  width: 100%; height: 100%; object-fit: contain;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,0.15));
}
.logo-badge-fallback{
  display:none; align-items:center; justify-content:center;
  position:absolute; inset:0;
  width:100%; height:100%; color:#fff; font-size:1.2rem;
}
.sidebar-brand .brand-text .name{
  font-family: var(--font-display) !important;
  font-weight: 800 !important;
  font-size: 1.02rem !important;
  letter-spacing: -0.01em;
  color: var(--ink-900) !important;
}
.sidebar-brand .brand-text .tagline{
  color: var(--slate-500) !important;
  font-weight: 500;
}

.sidebar-nav .nav-section-label{
  color: var(--slate-300) !important;
  font-size: .66rem !important;
  text-transform: uppercase;
  letter-spacing: .11em !important;
  font-weight: 700 !important;
  margin-top: .4rem;
}

.sidebar-nav a.nav-link-item{
  border-radius: var(--radius-sm) !important;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: .89rem !important;
  color: var(--slate-700) !important;
  display: flex; align-items: center; gap: .7rem;
  padding: .58rem .75rem !important;
  margin-bottom: 3px;
  transition: background-color .15s ease, color .15s ease, transform .15s ease;
}
.sidebar-nav a.nav-link-item i{
  color: var(--slate-300) !important;
  font-size: 1.02rem;
  width: 22px; text-align: center;
  transition: color .15s ease;
}
.sidebar-nav a.nav-link-item:hover{
  background-color: var(--paper) !important;
  color: var(--ink-900) !important;
  transform: translateX(2px);
}
.sidebar-nav a.nav-link-item:hover i{ color: var(--accent-500) !important; }

.sidebar-nav a.nav-link-item.active{
  background: var(--accent-100) !important;
  color: var(--accent-600) !important;
  font-weight: 700;
  position: relative;
}
.sidebar-nav a.nav-link-item.active::before{
  content:"" !important;
  position:absolute; left:-0.75rem; top:8px; bottom:8px; width:3px;
  border-radius: 0 3px 3px 0;
  background: var(--accent-500) !important;
}
.sidebar-nav a.nav-link-item.active i{ color: var(--accent-600) !important; }

.sidebar-footer{
  border-top: 1px solid var(--line) !important;
  padding: 1rem 1.1rem !important;
}
.sidebar-footer .fw-semibold{ color: var(--ink-900) !important; }

.mobile-topbar{
  background: #FFFFFF !important;
  border-bottom: 1px solid var(--line);
  color: var(--ink-900) !important;
}
.mobile-topbar span{ color: var(--ink-900) !important; }

/* -------------------------------------------------------------------------
   Top utility bar
   ------------------------------------------------------------------------- */
.topbar{
  display:flex; align-items:center; justify-content:space-between;
  padding: .85rem 1.5rem;
  margin: -20px -20px 20px -20px;
  background: var(--paper-card);
  border-bottom: 1px solid var(--line);
}
.topbar .topbar-title{
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.02rem;
  color: var(--ink-900);
  display:flex; align-items:center; gap:.5rem;
}
.topbar .topbar-title small{
  font-family: var(--font-body);
  font-size: .72rem; color: var(--slate-500); font-weight:500;
  border-left: 2px solid var(--accent-500); padding-left:.6rem; margin-left:.2rem;
}
.topbar-actions{ display:flex; align-items:center; gap:.9rem; }
.topbar-icon-btn{
  width: 38px; height: 38px; border-radius: 50%;
  display:flex; align-items:center; justify-content:center;
  background: var(--paper); color: var(--slate-700);
  border: 1px solid var(--line); position:relative;
  text-decoration:none; transition: all .15s ease;
}
.topbar-icon-btn:hover{ background: var(--accent-100); color: var(--accent-600); }
.topbar-icon-btn .dot{
  position:absolute; top:6px; right:7px;
  width:8px; height:8px; border-radius:50%;
  background: var(--bad); border:1.5px solid #fff;
}
.topbar-profile{
  display:flex; align-items:center; gap:.6rem;
  padding: .3rem .7rem .3rem .3rem;
  border-radius: 999px; border: 1px solid var(--line);
  cursor:pointer; text-decoration:none; color: var(--slate-700);
}
.topbar-profile:hover{ background: var(--paper); }
.topbar-avatar{
  width: 30px; height: 30px; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent-500), var(--accent-600));
  color: #fff; font-family: var(--font-display); font-weight:700;
  display:flex; align-items:center; justify-content:center; font-size:.85rem;
}
.topbar-profile .profile-meta{ line-height:1.1; }
.topbar-profile .profile-meta .p-name{ font-size:.82rem; font-weight:600; color: var(--ink-900); }
.topbar-profile .profile-meta .p-role{ font-size:.7rem; color: var(--slate-500); }

@media (max-width: 767.98px){
  .content{ padding: 14px !important; }
  .topbar{ margin: -14px -14px 16px -14px; padding: .7rem 1rem; }
}

/* -------------------------------------------------------------------------
   Root cause of tables (and anything else wide) stretching the whole page
   sideways: .row (Bootstrap) is display:flex, and .content is a flex item.
   Flex items default to min-width:auto, meaning they refuse to shrink
   below the natural width of their deepest content — even content sitting
   inside a .table-responsive scroll wrapper several levels down. That lets
   a wide table drag the entire row/page wider than the screen instead of
   just scrolling inside its own wrapper. Forcing min-width:0 here lets the
   column shrink to the viewport properly so .table-responsive can do its job. */
.content, nav.sidebar{
  min-width: 0;
}

/* -------------------------------------------------------------------------
   Several pages (Setup, Tests, Attendance, Add/Manage Student, Fees,
   Revenue & Expenses, Dashboard) wrap their content in their own
   .container-fluid, but that content already sits inside .content
   (see header.php), which supplies its own padding. Left alone, this
   doubles up the padding — most visible as extra empty space above each
   page's own tab menu, and worst on mobile where space is tight.
   Instead of hand-editing the markup in every page, strip the
   duplicate padding at the source. */
.content > .container-fluid{
  padding-left: 0 !important;
  padding-right: 0 !important;
  padding-top: 0 !important;
  padding-bottom: 0 !important;
}

/* Revenue & Expenses adds "mt-4" on top of its tab menu's own "mb-3" —
   an extra, unintended gap directly above the tabs. */
.content .nav-tabs{ margin-top: 0 !important; }

/* -------------------------------------------------------------------------
   Cards
   ------------------------------------------------------------------------- */
.card{
  border: 1px solid var(--line) !important;
  border-radius: var(--radius-lg) !important;
  box-shadow: var(--shadow-card) !important;
  transition: box-shadow .2s ease;
}
.card.shadow-sm:hover{ box-shadow: var(--shadow-card-hover) !important; }

/* Neutralize stray Bootstrap border-color utilities used on forms (border-primary/border-info/etc.) */
.card.border-primary, .card.border-info, .card.border-success, .card.border-warning, .card.border-danger, .card.border-secondary{
  border-color: var(--line) !important;
  border-top: 3px solid var(--accent-500) !important;
}

.card-header{
  border-radius: var(--radius-lg) var(--radius-lg) 0 0 !important;
  border-bottom: none !important;
  font-weight: 700;
  padding: .9rem 1.2rem !important;
  font-family: var(--font-display);
}
.card-header.bg-dark{
  background: linear-gradient(120deg, var(--ink-800), var(--ink-700)) !important;
  position: relative;
}
.card-header.bg-dark::after{
  content:"";
  position:absolute; left:1.2rem; right:1.2rem; bottom:0;
  height:2px; background: linear-gradient(90deg, var(--accent-500), transparent);
}
.card-header.bg-white{ background: #fff !important; }
.card-body{ padding: 1.25rem !important; }

.card-kpi{ overflow:hidden; position:relative; }
.card-kpi::before{
  content:""; position:absolute; top:0; left:0; bottom:0; width:4px;
  background: var(--accent-500);
}
.card-kpi h3, .card-kpi h4{ color: var(--ink-900); }

/* Headings inside forms that used Bootstrap's default blue/cyan text utilities */
.text-primary{ color: var(--accent-600) !important; }

/* -------------------------------------------------------------------------
   Tables
   ------------------------------------------------------------------------- */
.table{ margin-bottom:0; }
.table thead.table-dark th, .table thead.table-light th, .table > :not(caption) > * > th{
  font-family: var(--font-body);
  font-size: .72rem; text-transform: uppercase; letter-spacing:.06em;
  font-weight:700;
}
.table thead.table-dark, table thead.table-dark th{
  background: var(--ink-800) !important; color:#fff !important; border-color: var(--ink-800) !important;
}
.table thead.table-light, table thead.table-light th{
  background: var(--paper) !important; color: var(--slate-700) !important; border-color: var(--line) !important;
}
.table-striped>tbody>tr:nth-of-type(odd)>*{ background-color: rgba(76,110,245,0.03); }
.table-hover>tbody>tr:hover>*{ background-color: var(--accent-100) !important; }
.table td, .table th{ vertical-align: middle; padding: .7rem .8rem; }
.table-responsive{ border-radius: var(--radius-md); -webkit-overflow-scrolling: touch; }

/* -------------------------------------------------------------------------
   Mobile card layout for data-heavy tables (opt-in via .table-card-mobile).
   Below 768px, a wide table forces sideways scrolling inside its own
   .table-responsive wrapper — technically contained now, but still an
   awkward way to read a record on a phone. Instead, collapse each <tr>
   into a bordered card and lay its cells out as label:value rows, using
   each <td>'s data-label attribute as the row's caption.
   ------------------------------------------------------------------------- */
@media (max-width: 767.98px){
  .table-card-mobile thead{ display:none; }
  .table-card-mobile, .table-card-mobile tbody, .table-card-mobile tr, .table-card-mobile td{
    display:block; width:100%;
  }
  .table-card-mobile{ background: transparent !important; }
  .table-card-mobile tr{
    margin-bottom: .9rem;
    border: 1px solid var(--line) !important;
    border-radius: var(--radius-md);
    overflow: hidden;
    box-shadow: var(--shadow-card);
  }
  .table-card-mobile tr:last-child{ margin-bottom: 0; }
  .table-card-mobile tbody tr:nth-of-type(odd) > *{ background: transparent !important; }
  .table-card-mobile td{
    display: block;
    text-align: left;
    padding: .55rem .9rem !important;
    border: none !important;
    border-bottom: 1px solid var(--line) !important;
  }
  .table-card-mobile td:last-child{ border-bottom: none !important; }
  .table-card-mobile td::before{
    content: attr(data-label);
    display: block;
    font-family: var(--font-body);
    font-size: .68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--slate-500);
    margin-bottom: .2rem;
  }
  /* A full-width colspan row (e.g. "no records found") has no data-label —
     show it as plain centered text instead of a label:value pair. */
  .table-card-mobile td[colspan]{
    text-align: center !important;
  }
  .table-card-mobile td[colspan]::before{ content: none; }
}

/* -------------------------------------------------------------------------
   Forms
   ------------------------------------------------------------------------- */
.form-label{ font-size:.81rem; font-weight:600; color: var(--ink-800); margin-bottom:.35rem; }
.form-control, .form-select{
  border-radius: var(--radius-sm) !important;
  border: 1px solid var(--line) !important;
  padding: .55rem .8rem !important;
  font-size: .92rem;
}
.form-control:focus, .form-select:focus{
  border-color: var(--accent-500) !important;
  box-shadow: 0 0 0 3px var(--accent-100) !important;
}
.form-text{ font-size:.78rem; color: var(--slate-500); }

/* -------------------------------------------------------------------------
   Buttons
   ------------------------------------------------------------------------- */
.btn{ border-radius: var(--radius-sm) !important; font-weight:600; padding:.5rem 1.1rem; }
.btn-primary{ background: var(--accent-500) !important; border-color: var(--accent-500) !important; }
.btn-primary:hover{ background: var(--accent-600) !important; border-color: var(--accent-600) !important; }
.btn-outline-secondary{ border-color: var(--line) !important; color: var(--slate-700) !important; }
.btn-outline-secondary:hover{ background: var(--slate-700) !important; border-color: var(--slate-700) !important; color:#fff !important; }
.btn-warning{ background: var(--warn) !important; border-color: var(--warn) !important; color:#fff !important; }
.btn-outline-warning{ color: var(--warn) !important; border-color: var(--warn) !important; }
.btn-outline-warning:hover{ background: var(--warn-bg) !important; color: var(--ink-900) !important; }
.btn-outline-danger:hover{ background: var(--bad-bg) !important; }
.btn-info{ background-color: var(--info) !important; border-color: var(--info) !important; color:#fff !important; }
.btn-info:hover{ background-color: #1E4399 !important; border-color: #1E4399 !important; color:#fff !important; }
.btn-outline-info{ color: var(--info) !important; border-color: var(--info) !important; }
.btn-outline-info:hover{ background-color: var(--info) !important; color:#fff !important; }

/* -------------------------------------------------------------------------
   Badges & alerts
   ------------------------------------------------------------------------- */
.badge{ border-radius: 999px !important; font-weight:600; padding:.4em .75em; font-size:.72rem; letter-spacing:.02em; }
.bg-success{ background-color: var(--ok) !important; }
.bg-danger{ background-color: var(--bad) !important; }
.bg-primary{ background-color: var(--accent-600) !important; }
.bg-info{ background-color: var(--info) !important; color:#fff !important; }
.bg-warning{ background-color: var(--warn) !important; color:#fff !important; }
.bg-secondary{ background-color: var(--slate-500) !important; }
.bg-light{ background-color: #F0F2F8 !important; }
.text-info{ color: var(--info) !important; }
.text-warning{ color: var(--warn) !important; }

.alert{ border-radius: var(--radius-md) !important; border: none !important; border-left: 4px solid transparent !important; font-size:.9rem; }
.alert-success{ background: var(--ok-bg) !important; color: var(--ok) !important; border-left-color: var(--ok) !important; }
.alert-danger{ background: var(--bad-bg) !important; color: var(--bad) !important; border-left-color: var(--bad) !important; }
.alert-warning{ background: var(--warn-bg) !important; color: var(--warn) !important; border-left-color: var(--warn) !important; }
.alert-info{ background: var(--info-bg) !important; color: var(--info) !important; border-left-color: var(--info) !important; }

/* -------------------------------------------------------------------------
   Nav tabs (Reports, Setup: Courses/Teachers/Batches)
   ------------------------------------------------------------------------- */
.nav-tabs{ border-bottom: 1px solid var(--line); gap:.25rem; }
.nav-tabs .nav-link{
  border:none !important; color: var(--slate-500); font-weight:600;
  font-family: var(--font-display);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0 !important;
  padding: .6rem 1.1rem;
}
.nav-tabs .nav-link:hover{ color: var(--ink-900); }
.nav-tabs .nav-link.active{
  color: var(--accent-600) !important; background: var(--paper-card) !important;
  box-shadow: inset 0 -3px 0 var(--accent-500);
}

/* -------------------------------------------------------------------------
   Empty states
   ------------------------------------------------------------------------- */
.empty-state{ text-align:center; padding: 3rem 1.5rem; color: var(--slate-500); }
.empty-state i{ font-size: 2.2rem; color: var(--accent-400); display:block; margin-bottom:.75rem; }
.empty-state .empty-title{ font-family: var(--font-display); color: var(--ink-900); font-size:1.05rem; margin-bottom:.25rem; }

/* -------------------------------------------------------------------------
   Login page
   ------------------------------------------------------------------------- */
.auth-shell{ min-height:100vh; display:flex; background:#F4F6FB; }
.auth-brand-panel{
  flex:1.1; position:relative; overflow:hidden;
  background: linear-gradient(165deg, var(--paper, #F4F6FB) 0%, var(--accent-100, #EAEFFF) 100%);
  color: var(--ink-900, #0A0F1C); display:flex; flex-direction:column; justify-content:center;
  padding: 4rem;
}
.auth-brand-panel::before{
  content:""; position:absolute; inset:0;
  background-image: radial-gradient(rgba(52,82,217,0.12) 1px, transparent 1px);
  background-size: 22px 22px;
  opacity:.7;
}
.auth-seal{
  width:64px; height:64px; border-radius: 16px;
  background: linear-gradient(135deg, var(--ink-800, #111A2E), var(--ink-900, #0A0F1C));
  display:flex; align-items:center; justify-content:center;
  font-family: var(--font-display); font-weight:800; font-size:1.6rem; color:#fff;
  box-shadow: 0 8px 22px rgba(10,15,28,0.28);
  position:relative; z-index:1; margin-bottom:2rem;
  padding: 9px;
}
.auth-seal-img{
  width:100%; height:100%; object-fit: contain;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,0.15));
}
.auth-seal-fallback{
  display:none; align-items:center; justify-content:center;
  position:absolute; inset:0;
  width:100%; height:100%; color:#fff;
  font-family: var(--font-display); font-weight:800; font-size:1.6rem;
}
.auth-brand-panel h1{
  color: var(--ink-900, #0A0F1C); font-size:2.1rem; position:relative; z-index:1; max-width:420px;
}
.auth-brand-panel h1::after{ display:none; }
.auth-brand-panel p{ color: var(--slate-500, #6B7290); position:relative; z-index:1; max-width:380px; }
.auth-form-panel{
  flex:1; display:flex; align-items:center; justify-content:center;
  background: var(--paper-card, #FFFFFF); padding: 2rem;
}
.login-card{
  width:100%; max-width:400px; border:1px solid var(--line, #E4E8F1) !important;
  border-radius: var(--radius-lg, 16px) !important; box-shadow: var(--shadow-card, 0 2px 10px rgba(10,15,28,0.06), 0 1px 2px rgba(10,15,28,0.05)) !important;
  background: var(--paper-card, #FFFFFF);
}
@media (max-width: 900px){
  .auth-brand-panel{ display:none; }
  .auth-form-panel{ background: linear-gradient(165deg, var(--paper, #F4F6FB) 0%, var(--accent-100, #EAEFFF) 100%); }
}

/* Scrollbar polish */
::-webkit-scrollbar{ width:16px; height:16px; }
::-webkit-scrollbar-thumb{ background: var(--slate-300); border-radius:8px; }
::-webkit-scrollbar-thumb:hover{ background: var(--slate-400, #9AA1B5); }
::-webkit-scrollbar-track{ background: transparent; }

/* -------------------------------------------------------------------------
   Scrollable lists — Add Fee / Record Payment student picker (shared by
   both flows: the "Add" button on a row and the standalone "Record
   Payment" trigger both open the same #addFeeModal / #modalStudentList),
   and the per-student Ledger's Payment History list. Long result sets now
   scroll inside a fixed-height box instead of pushing the modal past the
   viewport.
   ------------------------------------------------------------------------- */
#modalStudentList{
  overflow: visible;
}
@media (min-width: 768px){
  #modalStudentList{
    column-count: 2;
    column-gap: .5rem;
  }
  #modalStudentList > .list-group-item{
    break-inside: avoid;
    margin-bottom: -1px; /* keep list-group's collapsed-border look inside columns */
  }
}

.ledger-history-scroll{
  max-height: 320px;
  overflow-y: auto;
}
.ledger-history-scroll table thead th{
  position: sticky;
  top: 0;
  z-index: 1;
}
.ledger-history-scroll::-webkit-scrollbar{ width:10px; height:10px; }
.ledger-history-scroll::-webkit-scrollbar-thumb{ background: var(--slate-300); border-radius:8px; }
.ledger-history-scroll::-webkit-scrollbar-track{ background: transparent; }

/* -------------------------------------------------------------------------
   Defensive fallback: force scroll-within-modal behavior for the Record
   Payment and Ledger modals even if Bootstrap's own .modal-dialog-scrollable
   sizing gets overridden or loads late. Without this, tall modal content
   (long student lists, full ledgers) was overflowing the viewport with no
   scrollbar, instead of scrolling inside the modal body.
   ------------------------------------------------------------------------- */
#addFeeModal .modal-dialog,
#editFeeModal .modal-dialog,
div[id^="ledgerModal"] .modal-dialog{
  max-height: calc(100vh - 3.5rem);
  display: flex;
}
#addFeeModal .modal-content,
#editFeeModal .modal-content,
div[id^="ledgerModal"] .modal-content{
  max-height: calc(100vh - 3.5rem);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
/* addFeeModal (and editFeeModal) wrap header/body/footer inside a <form>,
   which sits between .modal-content and .modal-body. That extra layer
   isn't part of the flex chain above by default, so .modal-body never
   gets constrained to a scrollable height -- it just grows past the
   viewport. Make the form itself a flex column, AND make it actually
   fill (flex: 1 1 auto) the height .modal-content caps it to -- without
   that flex-grow, form just sizes to its own content like a normal
   block and the max-height/overflow:hidden above it simply clips the
   bottom off instead of making anything scrollable. */
#addFeeModal .modal-content > form,
#editFeeModal .modal-content > form{
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
/* Header and footer keep their natural size -- they must NOT grow or
   shrink, so all the leftover space is handed to modal-body below. */
#addFeeModal .modal-header,
#addFeeModal .modal-footer,
#editFeeModal .modal-header,
#editFeeModal .modal-footer,
div[id^="ledgerModal"] .modal-header,
div[id^="ledgerModal"] .modal-footer{
  flex: 0 0 auto;
}
/* modal-body gets whatever vertical space is left after the header and
   footer -- THIS flex-grow is what was missing. Without it, min-height:0
   and overflow-y:auto have nothing to act on, since the element was
   never actually squeezed smaller than its content in the first place. */
#addFeeModal .modal-body,
#editFeeModal .modal-body,
div[id^="ledgerModal"] .modal-body{
  flex: 1 1 auto;
  overflow-y: auto;
  min-height: 0;
}