/*
 * Phone-sized screens.
 *
 * Nothing here adds, removes or rearranges anything: every page keeps the same
 * controls in the same order. What changes is only what a finger and an eye
 * need — targets big enough to hit, text big enough to read, and rows of
 * buttons that wrap instead of being squeezed.
 *
 * The declarations are marked !important on purpose: several pages load their
 * own stylesheet, and many carry an inline <style> block, so this file — which
 * sits in the head — is not the last word on specificity alone. It is scoped to
 * <=767px, so the desktop never sees any of it.
 */
@media (max-width: 767px) {

  /* ── Targets a finger can hit ──────────────────────────────
     A fingertip covers about 9mm; anything under ~44px is a guess. Buttons
     keep their labels and their look, they simply stop being 26px tall. */
  .btn,
  a.btn,
  button.btn,
  .btn-group > .btn {
    min-height: 44px !important;
    padding-top: 10px !important;
    padding-bottom: 10px !important;
  }
  .btn-xs, .btn-sm { font-size: 13px !important; }

  /* Icon buttons in a table row: square and reachable, not a 20px glyph.
     40px was close but under the 44 every other control on this page uses,
     and these two - edit and delete - are the ones a thumb reaches for most. */
  table td .btn,
  table td a.btn,
  .table td .btn,
  .dropdown-toggle.btn-xs {
    min-height: 44px !important;
    min-width: 44px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
  }
  /* A cell of actions wraps rather than forcing the table wider. */
  table td .btn-group,
  .table td .btn-group { display: inline-flex !important; flex-wrap: wrap !important; gap: 4px !important; }

  /* Paging is tapped more than anything else on a list - so it gets the
     same 44 as everything else, not four pixels less. */
  .dataTables_paginate .paginate_button,
  .pagination > li > a,
  .pagination > li > span {
    min-width: 44px !important;
    min-height: 44px !important;
    line-height: 26px !important;
  }

  /* ── Fields ────────────────────────────────────────────────
     16px is not a style choice: iOS zooms the whole page in when it focuses a
     field smaller than that, and the reader then has to pinch back out. */
  .form-control,
  input[type="text"], input[type="email"], input[type="password"],
  input[type="number"], input[type="tel"], input[type="date"], input[type="search"],
  select, textarea, .select2-selection--single {
    min-height: 44px !important;
    font-size: 16px !important;
  }
  textarea.form-control { min-height: 88px !important; }
  input[type="checkbox"], input[type="radio"] { width: 18px !important; height: 18px !important; }

  /* ── Counters (Book Meal, Meal Plan) ───────────────────────
     The minus and plus were 26px squares — the smallest targets in the app,
     and the ones pressed most often. */
  .bm-qty-btn { width: 40px !important; height: 40px !important; font-size: 18px !important; }
  .bm-qty-input { width: 42px !important; height: 40px !important; font-size: 15px !important; }
  .bm-qty-wrap { border-radius: 21px !important; }
  /* The per-period "Clear" is a link dressed as a button; at 30px it was the
     one control on Book Meal a thumb could still miss. */
  .bm-link-btn { min-height: 36px !important; padding: 8px 12px !important; }

  /* ── Text a phone can read ─────────────────────────────────
     10 and 11px belong to a desktop table, not to a hand at arm's length. */
  .bm-meal-name   { font-size: 13px !important; }
  .bm-meal-category { font-size: 11.5px !important; }
  .bm-meal-price  { font-size: 13px !important; }
  .bm-meal-booked, .bm-stock-badge { font-size: 11.5px !important; }
  /* The weekday under each date pill was 9px — the smallest type in the app. */
  .bm-day-name, .bm-day-num { font-size: 11.5px !important; }
  .admin-meal-cal__empty,
  .admin-meal-cal__period,
  .admin-meal-cal__holiday,
  .admin-meal-cal__dow-head { font-size: 11.5px !important; }
  .admin-meal-cal__count { font-size: 12px !important; }
  .mp-cell-empty, .mp-col-count { font-size: 12px !important; }
  small, .small { font-size: 12px !important; }
  .dash-ops-grid__label { font-size: 11.5px !important; }

  /* A tick box is 18px by design, but the words beside it are what a thumb
     actually aims at, so give them a row tall enough to hit.

     `display` is deliberately not !important. SweetAlert2 puts an unused
     `label.swal2-checkbox` in every dialog it builds and hides it with an
     inline `display: none`; !important beat that inline rule, so on a phone
     every dialog in the application - the logout confirmation among them -
     drew an empty tick box under its message. These selectors are specific
     enough to beat Bootstrap's `label { display: inline-block }` on their
     own, and a dialog's own hidden controls are excluded outright. */
  .checkbox-custom label,
  .radio-custom label,
  label:has(> input[type="checkbox"]):not(.swal2-checkbox),
  label:has(> input[type="radio"]):not(.swal2-radio) { min-height: 32px !important; display: inline-flex; align-items: center; gap: 6px; }

  /* Long labels beside a wide control: let them wrap instead of overflowing. */
  .panel-heading, .panel-footer { flex-wrap: wrap !important; }
}

/* ════════ A list table as cards ════════════════════════════════════
   A row of eight columns needs about 1100px. At 390px it sits in a box a
   third that wide and three quarters of its cells are off the screen, which
   is no way to read a list of your own bookings.

   A table marked `table-cards` becomes one card per row on a phone: every
   cell on its own line, labelled with the column it came from (each cell
   carries that name in data-label, so the labels are translated the same way
   the heading row is), and the buttons gathered at the foot of the card.
   Above 767px the table is a table. */
@media (max-width: 767px) {
  table.table-cards,
  table.table-cards > tbody,
  table.table-cards > tbody > tr,
  table.table-cards > tbody > tr > td { display: block !important; width: 100% !important; }
  table.table-cards { border: 0 !important; }
  table.table-cards > thead { display: none !important; }

  table.table-cards > tbody > tr {
    background: #fff; border: 1px solid var(--n-100) !important; border-radius: 12px;
    margin-bottom: 12px; overflow: hidden;
  }
  table.table-cards > tbody > tr > td {
    display: flex !important; align-items: flex-start; justify-content: space-between; gap: 12px;
    border: 0 !important; border-bottom: 1px solid var(--n-50) !important; padding: 9px 13px !important;
    text-align: left !important;
    /* Two inherited rules would push the value out of sight: cells are laid out
       content-box here, so a width of 100% plus padding came out wider than the
       card and was clipped by its rounded edge; and nowrap kept a long booking
       number on one line. */
    box-sizing: border-box !important;
    white-space: normal !important;
    flex-wrap: wrap; overflow-wrap: anywhere;
  }
  table.table-cards > tbody > tr > td:last-child { border-bottom: 0 !important; }
  table.table-cards > tbody > tr > td::before {
    content: attr(data-label);
    flex: 0 0 38%; color: var(--n-400); font-weight: 700; font-size: 10.5px;
    letter-spacing: .04em; text-transform: uppercase; padding-top: 2px;
  }
  /* A serial number is a table's crutch; a card does not need one. */
  table.table-cards > tbody > tr > td.tc-hide { display: none !important; }
  /* Where the rows come from the server, the view cannot mark the cell, so
     the table says instead that its first column is a serial number. */
  /* Not a one-cell row, though: "No data available" spans the whole table and
     is its first cell, so a phone showed an empty box (2026-10-10). */
  table.table-cards.tc-no-serial > tbody > tr > td:first-child:not([colspan]) { display: none !important; }
  /* An empty state is not a card: it is one line across the whole table. */
  table.table-cards > tbody > tr > td.dataTables_empty,
  table.table-cards > tbody > tr > td[colspan] { display: block !important; text-align: center !important; }
  table.table-cards > tbody > tr > td.dataTables_empty::before,
  table.table-cards > tbody > tr > td[colspan]::before { content: none; }
  /* Cells holding more than a word — a list of meals — read better underneath. */
  table.table-cards > tbody > tr > td.tc-block { display: block !important; }
  table.table-cards > tbody > tr > td.tc-block::before { display: block; margin-bottom: 5px; }
  /* The buttons belong together at the foot of the card. */
  table.table-cards > tbody > tr > td.action { flex-wrap: wrap; background: var(--n-25); }
  table.table-cards > tbody > tr > td.action::before { flex: 0 0 100%; margin-bottom: 6px; }
  table.table-cards > tbody > tr > td.action .btn,
  table.table-cards > tbody > tr > td.action form { margin: 0 6px 0 0; }

  /* The permission matrix is a card table whose rows are grouped under a
     module heading. That heading is a <th colspan> inside tbody, so none of
     the td rules above reach it; it stays one full-width bar between cards.
     Its checkbox column has nothing to label. */
  table.table-cards > tbody > tr.module-header-row > th {
    display: block !important; width: 100% !important;
    border: 0 !important; border-radius: 10px;
    background: var(--n-50); margin: 16px 0 8px; padding: 9px 12px !important;
  }
  table.table-cards > tbody > tr.module-header-row { border: 0 !important; background: transparent; }
  table.permission-table > tbody > tr > td.checkbox-cell:empty,
  table.permission-table > tbody > tr > td.checkbox-cell > :only-child:empty { display: none !important; }
  table.permission-table > tbody > tr > td { justify-content: flex-start !important; }
  table.permission-table > tbody > tr > td.feature-name-cell { font-weight: 600; background: var(--n-25); }

  /* A totals row is not a card: it is one line, the name on the left and the
     amount on the right. Its cells span several columns, so they carry no
     label of their own. */
  table.table-cards > tfoot,
  table.table-cards > tfoot > tr,
  table.table-cards > tfoot > tr > td { display: block !important; }
  table.table-cards > tfoot > tr {
    display: flex !important; justify-content: space-between; align-items: baseline; gap: 12px;
    background: #fff; border: 1px solid var(--n-100) !important; border-radius: 12px;
    margin-bottom: 8px; padding: 9px 13px;
  }
  table.table-cards > tfoot > tr > td {
    width: auto !important; border: 0 !important; padding: 0 !important;
    text-align: right !important; white-space: normal !important;
  }
  table.table-cards > tfoot > tr > td:first-child { text-align: left !important; }
  table.table-cards > tfoot > tr > td::before { content: none !important; }

  /* DataTables' own furniture, stacked rather than squeezed side by side. The
     search box already has its own rules for narrow screens in custom-style.css,
     so it is left alone here. */
  .dataTables_length,
  .dataTables_filter { float: none !important; text-align: left !important; }
  .dataTables_info,
  .dataTables_paginate { float: none !important; text-align: left !important; }
}
html.dark table.table-cards > tbody > tr { background: rgba(255,255,255,.04) !important; border-color: rgba(255,255,255,.12) !important; }
html.dark table.table-cards > tbody > tr > td.action { background: rgba(255,255,255,.03) !important; }

/* ════════ The menu button ════════════════════════════════════════
   On a phone the logo sits in a bar fixed over the top-left corner, and the
   menu button lives underneath it: every tap on the hamburger landed on the
   logo instead, so the sidebar could not be opened at all — the whole menu
   was unreachable. The button now sits above that bar, and the logo starts
   to the right of it so the two no longer overlap. */
@media (max-width: 767px) {
  .header .header-left .sidebar-toggle {
    position: relative !important;
    /* Above the open menu as well: the menu covers the whole screen, so the
       button that opened it is the only thing that can close it again. */
    z-index: 1300 !important;
  }

  /* ── A dropdown that is not a full-width panel ───────────────────────
     .header-menu > li is made position:static on a phone so the notification
     and message panels can span the screen (left:15px; right:15px). The
     language menu is a plain Bootstrap dropdown, though: it asks for
     top:100% of its li, and with the li static that became 100% of the page,
     so the list opened at the very bottom of the screen instead of under the
     globe. The panels keep the old behaviour; everything else gets its own
     li back to hang from. */
  .header-menu > li:has(> .dropdown-menu:not(.header-menubox)) {
    position: relative !important;
  }

  /* The panels that do span the screen had the other half of the same
     problem: with the li static and top:auto, their vertical position was
     whatever the flex row's static position happened to be — the
     notifications panel opened 13px above the top of the screen, with its
     first row cut off. Anchoring them to the header itself puts them under
     it, whatever height it is. */
  html .header { position: relative; }
  .header-menu > li .header-menubox {
    top: 100% !important;
    margin-top: 6px !important;
  }

  /* ── The logo belongs at the top, not over the page ──────────────────
     The mobile header pinned .logo-env with position:fixed, so the logo and
     the slogan hung in a 175px box at the top-left corner and the page slid
     underneath them: on a long screen — the booking calendar, a bill — the
     mark sat squarely on top of the content the whole way down.

     It goes back into the flow as a row of its own: the header wraps, the
     logo takes the first line across the full width and centred, and the
     menu button and the icons share the line below it. Nothing moves or is
     removed; the logo simply stops floating. */
  html .header {
    flex-wrap: wrap !important;
  }
  html .header .logo-env {
    position: static !important;
    order: -1;
    width: 100% !important;
    min-width: 0 !important;
    max-width: none !important;
    height: auto !important;
    justify-content: center !important;
    /* The 15px it was indented by belonged to a left-aligned bar. */
    padding-left: 0 !important;
    padding-right: 0 !important;
  }
  html .header .logo-env .logo {
    margin-left: 0 !important;
    text-align: center !important;
    justify-content: center !important;
  }
  /* It is 48px tall inside a 60px row, so without stretching it the bar it
     shares with the icons has a notch cut out of it under the button. */
  html .header .header-left {
    order: 1;
    flex: 0 0 auto;
    align-self: stretch;
    height: auto !important;
    display: flex;
    align-items: center;
  }
  /* The 60px it was pushed down by, and the full width it was given, both
     existed only to clear the fixed logo bar. With the logo on its own line
     the button and the icons sit side by side again. */
  html .header .header-right {
    order: 2;
    flex: 1 1 0;
    min-width: 0;
    width: auto !important;
    margin-top: 0 !important;
  }

  /* Open, the menu covers the screen. The page's own title bar carries a far
     higher stacking number than the sidebar, so without this it painted over
     the menu and swallowed the taps meant for it. */
  html.mob-menu-open .sidebar-left {
    left: 0 !important;
    margin-left: 0 !important;
    z-index: 1200 !important;
  }
  /* The last items - Users on an admin's menu - sat under the browser's own
     bottom toolbar. The menu is as tall as the screen with the toolbars
     hidden (100vh, or fixed to a bottom edge that some browsers, Samsung
     Internet among them, draw their toolbar over), so its end was out of
     reach however far it scrolled. It is the height of what can actually be
     seen (100dvh) where the browser knows that, and the list ends with room
     to bring its last item clear of any toolbar or a phone's home bar. */
  @supports (height: 100dvh) {
    html.fixed .sidebar-left {
      bottom: auto !important;
      height: 100dvh !important;
    }
  }
  html .sidebar-left .nano-content {
    padding-bottom: calc(110px + env(safe-area-inset-bottom, 0px)) !important;
  }
}

/* ════════ The customer's balance badge ═══════════════════════════
   Only customers get the wallet badge in the top bar, and on a 390px phone
   "BALANCE ৳1,234.00" plus the food-card icon pushed the header 51px past
   the screen — every page they open, chat included, scrolled sideways. The
   figure is the part that matters, so the word above it goes and the badge
   keeps the icon and the amount. */
@media (max-width: 767px) {
  .header .header-right .navbar-wallet-badge .wallet-label { display: none !important; }
  .header .header-right .navbar-wallet-badge {
    padding: 6px 10px !important;
    gap: 5px !important;
  }
  .header .header-right .header-menu-item { margin-right: 4px !important; }
}

/* ════════ Dashboard cards on a phone ═════════════════════════════
   The stat card is pinned to 84px tall, and its content box centres what is
   inside and hides the overflow. That works at desktop width, where a card is
   250px across and a caption fits on one line. At 160px — two cards to a
   390px screen — a card with a caption needs 122px, so 19px were cut off top
   and bottom, and since the box centres its content it was the number at the
   top that went: "Snack / September 2026" with no count at all, on every meal
   period, on This Week, In Transit and To Prepare. The amounts fared no
   better: 788.78 was ellipsised to "৳78…".

   On a phone the card takes the height it needs. Cards in a row are flex
   items, so they still finish level with each other. */
@media (max-width: 767px) {
  .dashboard-role-stats .stat-card-custom {
    height: auto !important;
    min-height: 84px !important;
    max-height: none !important;
  }
  .dashboard-role-stats .stat-content-box {
    overflow: visible !important;
    justify-content: center !important;
  }
  /* A figure is the one thing on the card that must never be abbreviated, so
     it wraps rather than truncating. Sized so the amounts this app actually
     shows still land on one line: 788.78 at 19px did not, and broke after the
     "7". The icon gives up a few pixels for the same reason. */
  .dashboard-role-stats .stat-count-text {
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
    overflow-wrap: anywhere !important;
    font-size: 17px !important;
  }
  .dashboard-role-stats .stat-icon-box {
    width: 36px !important;
    height: 36px !important;
    min-width: 36px !important;
    font-size: 15px !important;
  }
  /* Two lines are held on every desktop tile to keep a row level; the row is
     levelled by flex here, so the empty line is just a gap. */
  .dashboard-role-stats .stat-label-text {
    min-height: 0 !important;
  }
}

/* The Financial Health tile puts a label and a figure on one line, each told
   to ellipsise rather than wrap. In a 160px card that gave "Wallet Bala…"
   against "৳0…." — neither the word nor the number. On a phone they stack. */
@media (max-width: 767px) {
  .admin-fin-health__item {
    display: block !important;
  }
  .admin-fin-health__label,
  .admin-fin-health__value {
    display: block !important;
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
    text-align: left !important;
    overflow-wrap: anywhere !important;
  }
}

/* The "Unread" badge on the notification list is a submit button now, and a
   19px-tall badge is not something a thumb hits. It keeps the badge look and
   gains a target. 34px was the first attempt and still short of the 44 every
   other control on a phone uses; this is the button that marks a notification
   read, so it gets the same. */
@media (max-width: 767px) {
  .nc-read-btn {
    min-height: 44px !important;
    padding: 8px 14px !important;
    font-size: 12px !important;
  }
  .nc-read-form {
    display: inline-block !important;
  }
}
