/* ==========================================================================
   CNQ Business Suite — phone-viewport corrections

   Loaded from layout/header.php, which every one of the suite's ~140 pages
   includes. That partial is required from inside <body>, so this sheet is
   in-body: valid, and the same pattern layout/sidebar.php (ai-pet.css) and
   layout/footer.php (bs-assistant.css) already use. It lands before
   #kt_app_header and before all page content, and first paint is already gated
   on the 1.5MB style.bundle.css in <head>, so the practical cost is nil.

   Being later in the cascade than style.bundle.css is deliberate: plain
   declarations already win at equal specificity. !important appears ONLY where
   it has to beat one of the theme's own !important utilities (.w-*px,
   .min-w-*px, .mw-*px, .text-end). Tap-target sizing uses min-width/min-height,
   which beat width/height in the used-value calculation without !important.

   Breakpoints mirror the theme's own so nothing fights:
     991.98px — style.bundle.css flips --bs-app-header-height 90px -> 60px,
                hides .app-sidebar, and switches .app-container padding
                35px -> 20px.
     767.98px / 575.98px — Bootstrap md/sm edges, phone-only rules.
   Every rule lives inside a max-width query: desktop cannot regress.
   ========================================================================== */


/* ==========================================================================
   1. HORIZONTAL PAGE SCROLL

   overflow-x: hidden on html or body is the wrong tool:

   (a) it turns that element into a SCROLL CONTAINER, and a position:sticky
       descendant sticks to its nearest scrollport — so re-rooting the
       scrollport silently changes every sticky descendant;
   (b) it only HIDES the overflow. An over-wide toolbar row is still over-wide;
       clipping it makes the right-hand button physically unreachable. That is a
       functional regression dressed up as a fix;
   (c) on iOS Safari, overflow-x on <body> while <html> still scrolls is
       unreliable and can misalign position:fixed chrome.

   So: remove the overflow at source (sections 2-3), and keep only a
   containment NET on the content column, using `overflow-x: clip` — which
   creates a clip container, NOT a scroll container, so sticky descendants keep
   their scrollport. `hidden` is the fallback for engines without `clip`.
   ========================================================================== */

@media (max-width: 991.98px) {

  /* Break the min-content floor down the whole layout chain. A flex/grid item
     refuses to shrink below its content's min-content width unless told it may
     — that is the actual mechanism behind the toolbar overflow. */
  #kt_app_root,
  #kt_app_page,
  #kt_app_wrapper,
  #kt_app_main,
  .app-main,
  .app-content,
  .app-container,
  .app-toolbar,
  .app-toolbar-wrapper {
    min-width: 0;
  }

  .app-content {
    overflow-x: clip;
  }
  @supports not (overflow: clip) {
    .app-content {
      overflow-x: hidden;
    }
  }

  /* Replaced elements must never set the page width. */
  .app-content img,
  .app-content svg,
  .app-content video,
  .app-content canvas,
  .app-content iframe,
  .app-content embed {
    max-width: 100%;
  }
  .app-content img,
  .app-content video {
    height: auto;
  }

  /* Unbreakable strings — GSTINs, emails, URLs, long company names.

     NOTE: `anywhere` (unlike `break-word`) COUNTS TOWARDS INTRINSIC SIZING, so
     on a table cell it drops the column's min-content width to one character.
     Section 6 takes it back off cells inside a .table-responsive for exactly
     that reason — read that section before adding a selector here. */
  .app-content .badge,
  .app-content td,
  .app-content th,
  .app-content .text-muted,
  .app-content .page-heading,
  .app-content .breadcrumb-item {
    overflow-wrap: anywhere;
  }

  .app-content pre {
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }
}


/* ==========================================================================
   2. TOOLBAR / ACTION ROWS

   .app-toolbar-wrapper has zero rules in style.bundle.css, so it is a free
   hook with nothing to override. Three markup shapes exist and all are covered:

     A. an inner `div.d-flex` holding N buttons  (the common case)
     B. a bare .btn as a DIRECT child of .app-toolbar-wrapper
     C. already correct — a container that carries flex-wrap. Idempotent here.
   ========================================================================== */

@media (max-width: 991.98px) {

  /* Every direct child may shrink and must not exceed the wrapper. This alone
     stops an action row from forcing the page width. */
  .app-toolbar-wrapper > * {
    min-width: 0;
    max-width: 100%;
  }

  /* Shape A. Harmless on the left-hand heading column. */
  .app-toolbar-wrapper > .d-flex {
    flex-wrap: wrap;
  }

  /* Buttons wrap as whole units rather than squashing to unreadable widths. */
  .app-toolbar-wrapper .btn {
    flex: 0 1 auto;
  }
}

@media (max-width: 575.98px) {

  /* Stack heading above actions; give the action row the full width. */
  .app-toolbar-wrapper {
    flex-direction: column;
    align-items: stretch;
  }

  .app-toolbar-wrapper > .d-flex {
    width: 100%;
  }

  /* Shapes A and B: buttons share the row and reach a comfortable width. */
  .app-toolbar-wrapper > .d-flex > .btn,
  .app-toolbar-wrapper > .btn {
    flex: 1 1 auto;
    justify-content: center;
  }

  /* The CRM dashboard's "Last sync" block is a .text-end sibling of five
     buttons. Promote it to its own full-width line and left-align it.
     .text-end is `text-align: right !important`, hence the !important. */
  .app-toolbar-wrapper > .d-flex > .text-end {
    flex: 1 0 100%;
    text-align: left !important;
    margin-right: 0 !important;   /* cancels its me-2 */
  }

  .app-toolbar-wrapper .page-heading {
    overflow-wrap: anywhere;
  }
}


/* ==========================================================================
   3. FIXED-WIDTH UTILITIES THAT FORCE CONTENT WIDTH

   The theme's px utilities are all !important (.w-35px { width: 35px
   !important }, .min-w-250px { min-width: 250px !important }, .mw-650px
   { max-width: 650px !important }), so width/max-width overrides need
   !important too.

   The min-w-* list is exactly the set actually used in the suite. 50/80/90px
   are left alone — they fit a 360px viewport and are usually deliberate.
   ========================================================================== */

@media (max-width: 575.98px) {

  .min-w-250px, .min-w-240px, .min-w-220px, .min-w-200px, .min-w-180px,
  .min-w-170px, .min-w-160px, .min-w-150px, .min-w-140px, .min-w-130px,
  .min-w-125px, .min-w-120px, .min-w-115px, .min-w-110px, .min-w-100px {
    min-width: 0 !important;
  }
}

@media (max-width: 991.98px) {

  /* Header dropdown panels. .menu-sub-dropdown has NO max-width anywhere in
     style.bundle.css, and the widest are 350px/300px/275px — i.e. wider than,
     or nearly as wide as, a 360px phone. */
  .menu-sub-dropdown {
    max-width: calc(100vw - 1.5rem) !important;
  }

  .menu-sub-dropdown.w-350px,
  .menu-sub-dropdown.w-300px,
  .menu-sub-dropdown.w-275px {
    width: calc(100vw - 1.5rem) !important;
  }

  /* A `row g-0` of four `col-6` inside the 250px quick-links panel leaves
     ~77px per cell. One column on a phone. */
  .menu-sub-dropdown .row > .col-6 {
    flex: 0 0 100%;
    max-width: 100%;
  }

  /* A rigid `w-70px` badge next to free-flowing message text. */
  .menu-sub-dropdown .w-70px {
    width: auto !important;
    min-width: 0 !important;
  }

  /* Flex text columns in the panels have no min-width:0 and no text-truncate. */
  .menu-sub-dropdown .flex-stack > *,
  .menu-sub-dropdown .d-flex > * {
    min-width: 0;
  }
  .menu-sub-dropdown .flex-stack {
    flex-wrap: wrap;
  }
}


/* ==========================================================================
   4. SAFE-AREA INSETS (notched phones)

   REQUIRES `viewport-fit=cover` in the page's viewport meta — without it every
   env(safe-area-inset-*) resolves to 0px and this section is inert.

   The 20px base matches the theme's own below-lg .app-container padding; the
   0.75rem matches the footer's py-3.
   ========================================================================== */

@media (max-width: 991.98px) {

  .app-container {
    padding-left:  calc(20px + env(safe-area-inset-left, 0px))  !important;
    padding-right: calc(20px + env(safe-area-inset-right, 0px)) !important;
  }

  /* .app-header is position:fixed below lg. */
  .app-header {
    padding-left:  env(safe-area-inset-left, 0px);
    padding-right: env(safe-area-inset-right, 0px);
  }

  .app-footer {
    padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
  }

  /* Both off-canvas panels become .drawer once KTDrawer runs. */
  #kt_app_sidebar.drawer {
    padding-left:   env(safe-area-inset-left, 0px);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  #kt_app_aside.drawer {
    padding-right:  env(safe-area-inset-right, 0px);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
}


/* ==========================================================================
   5. 44px MINIMUM TAP TARGETS

   At the below-lg root size of 12px: .btn ~40.4px, .btn-sm ~32.3px,
   .btn-icon ~40.4px, .w-35px/.h-35px = 35px !important. All under 44px.

   Two techniques, chosen per context:

   (a) In the toolbar and content, buttons now WRAP (section 2), so there is
       room to grow them. min-height/min-width is used deliberately: min-*
       beats width/height in the used-value calculation regardless of
       !important, so it overrides .w-35px cleanly.

   (b) In the HEADER there is NO room — .app-navbar already carries ~403px of
       intrinsic content in a 360px viewport, so growing the boxes makes the
       overflow worse. An ::after overlay expands the HIT AREA to 44px without
       changing layout size.
   ========================================================================== */

@media (max-width: 991.98px) {

  /* (a) Content + toolbar buttons. */
  .app-content .btn:not(.btn-icon):not(.btn-flush),
  .app-toolbar-wrapper .btn:not(.btn-icon):not(.btn-flush) {
    min-height: 44px;
    padding-top: 0.55rem;
    padding-bottom: 0.55rem;
  }

  .app-content .btn.btn-icon,
  .app-toolbar-wrapper .btn.btn-icon {
    min-height: 44px;
    min-width: 44px;
  }

  /* Inputs in the same rows should match, or the row looks broken. */
  .app-content .form-control,
  .app-content .form-select {
    min-height: 44px;
  }

  /* Table row actions: 44px would blow out row height, and 40px plus the
     theme's generous row padding already gives a >=44px effective target. */
  .app-content .table .btn.btn-sm {
    min-height: 40px;
  }

  /* (b) Header hit-area overlays — layout, and so the tight header row, is
     untouched. */
  #kt_app_sidebar_mobile_toggle,
  #kt_app_aside_mobile_toggle,
  .search-toggle-mobile,
  .app-navbar-item > .btn.btn-icon,
  .app-navbar-item .cursor-pointer.symbol {
    position: relative;
  }

  #kt_app_sidebar_mobile_toggle::after,
  #kt_app_aside_mobile_toggle::after,
  .search-toggle-mobile::after,
  .app-navbar-item > .btn.btn-icon::after,
  .app-navbar-item .cursor-pointer.symbol::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 44px;
    height: 44px;
    /* no background: invisible, purely a pointer target */
  }

  /* The app rail already passes at 45px. This fixes its double-spacing bug:
     the wrapper has gap-4 AND every link has mb-4, giving 32px instead of 16px
     between 11 icons — about 847px of rail on a 640px-tall phone. */
  #kt_app_aside_wrapper > .cnq-app-rail-link {
    margin-bottom: 0 !important;
  }
}


/* ==========================================================================
   6. RESPONSIVE TABLES

   .table-responsive already has overflow-x:auto and
   -webkit-overflow-scrolling:touch, but NOT overscroll-behavior (which appears
   nowhere in the bundle) — so flicking past the end of a table scrolls the page
   behind it.

   It also only scrolls a table that is actually WIDER than the strip. 127 of
   the suite's 134 tables are already wrapped, so nothing here is about missing
   markup: the tables were being allowed to compress to nothing instead of
   overflowing. That is what the rules below undo, once, for every wrapped
   table in the suite.
   ========================================================================== */

@media (max-width: 991.98px) {

  .table-responsive {
    overscroll-behavior-x: contain;
  }

  /* Descendant combinator, not `>`. DataTables 1.13 (all five HRMS list pages
     plus most of CRM/finance) reparents the table into
     .table-responsive > .dataTables_wrapper > .row > .col-sm-12, so a child
     selector silently stops matching the moment the plugin initialises. */
  .table-responsive .table {
    margin-bottom: 0;
  }

  /* --- The letter-by-letter header bug ---------------------------------
     `E M P C O D E` stacked vertically is a column squeezed to ~1ch while
     still allowed to break. Three things have to hold for the scroll strip
     to do its job instead:

       (a) cells must report an HONEST min-content width, so section 1's
           `overflow-wrap: anywhere` is cancelled here — on the cell and on
           its descendants, because .badge and .text-muted are in that same
           list and both live inside these tables;
       (b) headers must never break mid-word — nowrap also makes the header
           label each column's width floor, which is what makes an
           11-column table honestly wider than a 360px viewport;
       (c) the table must be allowed to EXCEED .table-responsive, so the
           max-width cap below is lifted inside the strip.

     Together the table overflows, .table-responsive scrolls it, and nothing
     is clipped or stacked. Body cells still wrap at word boundaries, which
     is wanted — the free-text columns (case titles, "Reason / Self Review")
     must not become one enormous line. */
  .table-responsive .table th,
  .table-responsive .table td,
  .table-responsive .table th *,
  .table-responsive .table td * {
    overflow-wrap: normal;
  }

  .table-responsive .table > thead > tr > th {
    white-space: nowrap;
  }

  /* Defensive net for any table NOT in a scroll strip (the payslip and
     invoice document templates): stop it setting the page width. Pairs with
     .app-content's overflow-x: clip above. */
  .app-content table.table {
    max-width: 100%;
  }

  /* ...but never cap a table that HAS somewhere to overflow to: that cap is
     half of the squeeze this section exists to undo. */
  .app-content .table-responsive table.table {
    max-width: none;
  }

  /* A column narrower than ~8 characters cannot show a name, a status or a
     date without stacking it. Short headers ("Name", "Day", "Rating") do not
     supply a floor of their own, so give body cells one. Inert wherever the
     content is already wider, and section 3 has nulled the theme's own
     .min-w-*px utilities at phone width, so this is the only floor left. */
  .table-responsive .table > tbody > tr > td {
    min-width: 8ch;
  }
}

@media (max-width: 575.98px) {

  /* Reclaim horizontal room inside tables. */
  .table-responsive .table > :not(caption) > * > * {
    padding-left: 0.5rem;
    padding-right: 0.5rem;
  }
}


/* ==========================================================================
   7. PHONE-FRIENDLY MODALS

   Reproduces .modal-fullscreen-sm-down's effect for all 18 modal sites in the
   suite with no per-file edits.
   ========================================================================== */

@media (max-width: 575.98px) {

  .modal .modal-dialog {
    margin: 0;
    width: 100%;
    max-width: 100% !important;   /* beats .mw-900px / .mw-650px */
    min-height: 100%;
  }

  .modal .modal-content {
    min-height: 100dvh;           /* dvh, not vh: tracks the URL bar */
    border: 0;
    border-radius: 0;
  }
  @supports not (height: 100dvh) {
    .modal .modal-content {
      min-height: 100vh;
    }
  }

  .modal .modal-body {
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
  }

  .modal .modal-header,
  .modal .modal-footer {
    flex-wrap: wrap;
    row-gap: 0.5rem;
  }

  .modal .modal-footer > .btn {
    flex: 1 1 auto;
    min-height: 44px;
  }
}


/* ==========================================================================
   8. MOMENTUM + CONTAINMENT ON SCROLLING STRIPS

   overscroll-behavior appears nowhere in style.bundle.css, and
   -webkit-overflow-scrolling only on .table-responsive — so every scroller in
   the shared partials chains its scroll to the document on a phone.
   ========================================================================== */

@media (max-width: 991.98px) {

  .scroll-y,
  .scroll-x,
  .hover-scroll-y,
  .hover-scroll-x,
  .hover-scroll-overlay-y,
  .drawer {
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }

  /* footer.php disables KTScroll below lg, so let the rail wrapper scroll on
     its own rather than relying on .drawer { overflow: auto }. */
  #kt_app_aside.drawer #kt_app_aside_wrapper {
    overflow-y: auto;
    max-height: 100%;
  }
}

@media (max-width: 575.98px) {

  /* sidebar.php hard-codes data-kt-drawer-width="250px" — 69% of a 360px
     viewport, and unable to adapt to 320px devices. KTDrawer writes the width
     inline, so !important is required. */
  #kt_app_sidebar.drawer {
    width: min(86vw, 320px) !important;
  }
}


/* ==========================================================================
   9. USE THE THEME'S OWN LAYOUT VARS

   Below 992px the theme already sets --bs-app-header-height: 60px and
   --bs-app-aside-width: 80px. Referencing the vars keeps these rules correct
   through a theme upgrade, and under [data-kt-app-header-sticky=on], which
   rewrites the header var to 70px.
   ========================================================================== */

@media (max-width: 991.98px) {

  .app-content .min-vh-100 {
    min-height: calc(100dvh - var(--bs-app-header-height, 60px)) !important;
  }

  /* Scroll-into-view must clear the fixed header. */
  :target {
    scroll-margin-top: calc(var(--bs-app-header-height, 60px) + 0.5rem);
  }

  #kt_app_sidebar.drawer {
    max-width: calc(100vw - 3rem);
  }
  #kt_app_aside.drawer {
    max-width: min(calc(100vw - 3rem),
                   calc(var(--bs-app-aside-width, 80px) + 2rem));
  }
}


/* ==========================================================================
   10. OPT THE WHATSAPP INBOX OUT

   crm/whatsapp/assets/inbox.css is already mobile-hardened on its own terms:
   100dvh, env(safe-area-inset-bottom), overscroll-behavior: contain,
   -webkit-overflow-scrolling: touch, 44px composer controls, min-width:0 on its
   flex children, and it already reads var(--bs-app-header-height, 60px).

   It is linked in <head>, so THIS sheet is later in the cascade and would
   otherwise override its deliberate compact sizing. Opt out explicitly.
   ========================================================================== */

@media (max-width: 991.98px) {

  /* The inbox's pane headers use deliberately compact 34px controls; its
     composer already handles its own 44px targets. */
  .inbox-pane-header .btn,
  .inbox-pane-header .form-select,
  .inbox-pane-header .form-control,
  .inbox-filters .btn,
  .inbox-filters .form-select,
  .inbox-filters .form-control {
    min-height: 0;
  }

  /* The shell manages its own height against the viewport; the generic
     clip/min-width rules above must not reinterpret it. */
  .inbox-shell {
    min-width: 0;
  }
}
