/* ===========================================================================
   PS_RESPFLEET 2026-11-03 — responsive layer for the whole fleet.

   Every colour here comes from a --ps-* custom property that
   js/ps-responsive.js samples off the live page, so this one stylesheet looks
   native on both designs in the fleet:

     modern theme   panel rgb(30,38,44)  border rgb(44,56,64)  radius 12px
                    column headings grey rgb(225,232,237)
     classic theme  panel rgb(19,21,23)  border rgb(53,53,53)  radius 0
                    column headings pink rgb(229,51,152), rows striped

   The fallbacks after each var() are only for the moment before the script
   runs, or if it fails; they are deliberately neutral rather than aboshama3's
   palette, so a failure degrades to something plain instead of something wrong.

   Loaded after mobile-fix.css, which all 44 sites share byte for byte.
   =========================================================================== */


/* ---------------------------------------------------------------------------
   1. Let the badge row shrink

   css/mobile-fix.css (identical on every site) has:

       .span10:has(> .top-blockk) { display: flex !important;
                                    flex-wrap: nowrap !important; }

   That was written for the device board, where the children are small
   `.well.span3.top-blockk` badges meant to sit in a row. But the report pages
   put tiles and full-width panels in the same position, and a flex item
   defaults to `min-width: auto` - it will not shrink below its min-content
   width. Measured on gold-ps.xyz at a 320px viewport: the row refused to
   shrink and a tile's `.notification` badge ended up at x=902, dragging the
   whole document 582px wide.

   Two parts: let anything in that row shrink, and stop treating a full-width
   panel as if it were a badge.
   --------------------------------------------------------------------------- */
#content,
.span10:has(> .top-blockk),
.span10:has(> .top-blockk) > *,
.row-fluid > [class*="span"] {
    min-width: 0;
}

/* a full-width panel is not a badge row */
.span10:has(> .well.span11),
.span10:has(> .well.span12) {
    display: block !important;
}

/* the badge row itself may scroll sideways inside its own box, but the page
   must not */
.span10:has(> .top-blockk) {
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}


/* ---------------------------------------------------------------------------
   2. Data tables at every width

   Measured across the fleet: control_reservations.php runs 10-11 columns and
   1060px wide, reports.php 12 columns and 1039px, reports_day_shift.php 11
   columns. None of them sat in a scroll container, so they pushed the page
   sideways; cells were forced 550-642px wide.

   Two behaviours, because there are two different problems:

     up to 6 columns   scroll sideways inside the table's own box, with the
                       header pinned so the column stays identifiable
     7 or more         each row becomes a card with its own labels, read top
                       to bottom - you cannot hold eleven columns in your head
                       while dragging a scrollbar
   --------------------------------------------------------------------------- */

.ps-t-wrap {
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border-radius: var(--ps-radius, 0);
}

/* a scrollbar that belongs to the panel rather than the OS */
.ps-t-wrap::-webkit-scrollbar { height: 8px; }
.ps-t-wrap::-webkit-scrollbar-track {
    background: var(--ps-page-bg, transparent);
    border-radius: 999px;
}
.ps-t-wrap::-webkit-scrollbar-thumb {
    background: var(--ps-panel-border, rgba(255, 255, 255, 0.25));
    border-radius: 999px;
}
.ps-t-wrap {
    scrollbar-width: thin;
    scrollbar-color: var(--ps-panel-border, rgba(255, 255, 255, 0.25)) transparent;
}

/* js/ps-responsive.js hands the table's Bootstrap grid class to the wrapper so
   the wrapper keeps the table's place in the layout. Below 768px there are no
   columns to hold, so it gives up the grid width and spans the screen. */
@media (max-width: 767px) {
    .ps-t-wrap[class*="span"] {
        float: none !important;
        width: 100% !important;
        margin-left: 0 !important;
    }
}

/* ------------------------------------------- up to 6 columns: scroll ----- */
@media (max-width: 1100px) {
    .ps-t:not(.ps-t-stack) thead th {
        position: sticky;
        top: 0;
        z-index: 2;
        background: var(--ps-panel-bg, #1c1c1c) !important;
    }

    /* the first column is usually the name or the date: pin it so a row stays
       identifiable once the user has scrolled right */
    .ps-t:not(.ps-t-stack) tbody td:first-child,
    .ps-t:not(.ps-t-stack) thead th:first-child {
        position: sticky;
        inset-inline-start: 0;
        z-index: 1;
        background: var(--ps-panel-bg, #1c1c1c) !important;
    }
    .ps-t:not(.ps-t-stack) thead th:first-child { z-index: 3; }

    /* a hairline so the pinned column reads as pinned */
    .ps-t:not(.ps-t-stack) tbody td:first-child::after,
    .ps-t:not(.ps-t-stack) thead th:first-child::after {
        content: '';
        position: absolute;
        inset-block: 0;
        inset-inline-end: 0;
        width: 1px;
        background: var(--ps-panel-border, rgba(255, 255, 255, 0.2));
    }
}

/* -------------------------------------- 7+ columns: one card per row ----- */
@media (max-width: 767px) {
    .ps-t-stack {
        display: block;
        width: 100% !important;
        min-width: 0 !important;
        border: 0 !important;
        background: transparent !important;
    }

    /* the header is replaced by the per-cell labels */
    .ps-t-stack thead { display: none; }

    .ps-t-stack tbody,
    .ps-t-stack tfoot { display: block; width: 100%; }

    .ps-t-stack tbody tr {
        display: block;
        margin: 0 0 10px;
        padding: 2px 0;
        background: var(--ps-panel-bg, #1c1c1c) !important;
        border: 1px solid var(--ps-panel-border, rgba(255, 255, 255, 0.15));
        border-radius: var(--ps-radius, 0);
        overflow: hidden;
    }

    /* the classic theme stripes its rows rgb(51,51,51); striping would fight
       the card edges, so every card gets the panel fill instead */
    .ps-t-stack tbody tr:nth-child(odd),
    .ps-t-stack tbody tr:nth-child(even),
    .ps-t-stack tbody tr:hover {
        background: var(--ps-panel-bg, #1c1c1c) !important;
    }

    .ps-t-stack tbody td {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 14px;
        width: auto !important;
        padding: 9px 14px !important;
        border: 0 !important;
        border-bottom: 1px solid var(--ps-divider, rgba(255, 255, 255, 0.07)) !important;
        color: var(--ps-text, inherit);
        text-align: start !important;
        white-space: normal !important;
        overflow-wrap: break-word;
    }

    .ps-t-stack tbody td:last-child { border-bottom: 0 !important; }

    /* the label stands in for the column header, so it wears the header's own
       colour - pink on the classic theme, grey on the modern one */
    .ps-t-stack tbody td[data-label]::before {
        content: attr(data-label);
        flex: 0 0 40%;
        max-width: 45%;
        color: var(--ps-label, inherit);
        font-size: 12px;
        font-weight: 600;
        text-align: start;
        opacity: 0.85;
    }

    /* a cell holding only controls reads better wrapped under its label */
    .ps-t-stack tbody td:has(> .btn),
    .ps-t-stack tbody td:has(> form),
    .ps-t-stack tbody td:has(> a.btn),
    .ps-t-stack tbody td:has(> input) {
        flex-wrap: wrap;
        gap: 8px;
    }

    .ps-t-stack tbody td[align='right'],
    .ps-t-stack tbody td.num {
        font-variant-numeric: tabular-nums;
    }

    /* the totals row is a summary, not another record */
    .ps-t-stack tfoot tr {
        display: block;
        margin-top: 4px;
        background: var(--ps-page-bg, transparent) !important;
        border: 1px solid var(--ps-panel-border, rgba(255, 255, 255, 0.15));
        border-radius: var(--ps-radius, 0);
    }
    .ps-t-stack tfoot td {
        display: flex;
        justify-content: space-between;
        gap: 14px;
        padding: 10px 14px !important;
        border: 0 !important;
        font-weight: 700;
    }
    .ps-t-stack tfoot td[data-label]::before {
        content: attr(data-label);
        color: var(--ps-label, inherit);
        font-size: 12px;
        font-weight: 600;
        opacity: 0.85;
    }

    /* an empty DataTables message should not pretend to be a card */
    .ps-t-stack tbody td.dataTables_empty {
        display: block;
        text-align: center !important;
    }
    .ps-t-stack tbody td.dataTables_empty::before { content: none; }

    /* a stacked table needs no scroll container */
    .ps-t-wrap:has(> .ps-t-stack) { overflow-x: visible; }
}


/* ---------------------------------------------------------------------------
   3. Tap targets

   Counted on phones across the family representatives: 2 to 20 controls per
   site render under 36px tall. 44px is the smallest reliable touch target, and
   these tills are used on phones and tablets all day.

   Guarded on pointer type so a desktop keeps its compact controls, and scoped
   so it cannot reach the dense controls inside a table cell.
   --------------------------------------------------------------------------- */
@media (max-width: 991px) and (pointer: coarse) {
    html body .btn,
    html body button:not(.close),
    html body input[type="submit"],
    html body input[type="button"],
    html body select,
    html body .nav-link,
    html body .navbar .nav > li > a {
        min-height: 44px;
    }

    /* inputs and selects also need room for the text itself */
    html body select,
    html body input[type="text"],
    html body input[type="number"],
    html body input[type="password"],
    html body input[type="search"],
    html body input[type="date"] {
        min-height: 44px;
        font-size: 16px;   /* under 16px iOS Safari zooms the page on focus */
    }

    /* a table cell packs several controls into one row - leave those alone */
    html body td .btn,
    html body td button,
    html body td select,
    html body td input {
        min-height: 36px;
        font-size: 14px;
    }
}


/* ---------------------------------------------------------------------------
   4. Let long strings wrap

   Long unbroken text (device codes, serials, URLs) was forcing cells 550-642px
   wide on the reservation page, which is what dragged the document sideways.
   Allowing it to break is the actual fix.

   NOTE: deliberately no `html, body { overflow-x: hidden }` here. It would make
   the measurements read clean while hiding whatever still overflows, and on a
   page with no inner scroller it would clip data out of reach entirely. Sections
   1 and 2 remove the causes; anything still overflowing after that should show
   up in a measurement and get fixed where it happens.
   --------------------------------------------------------------------------- */
@media (max-width: 991px) {
    .ps-t td, .ps-t th,
    .top-blockk, .top-block {
        overflow-wrap: break-word;
        word-break: break-word;
    }
}


/* ---------------------------------------------------------------------------
   5. Panels that are wider than their own column

   Bootstrap 2 predates border-box sizing, so a panel given `width: 100%` adds
   its padding and border on top of that width. Measured at a 390px viewport:

     gold-ps.xyz       .box-content  computed width 378px, actual box 388px
     ps-hub.online     .box-content  computed width 378px, actual box 418px
                       .box.span6    a fixed 408px inside a 378px row

   Ten to forty pixels each, and because these pages are direction: rtl the
   excess runs off the left edge where it is easy to miss. It also expands the
   layout viewport - window.innerWidth measured 430 and 489 against a 390px
   screen - which then makes every position:fixed overlay (the nav drawer, the
   toast containers) report that inflated width too. Those overlays looked like
   the cause for a while; hiding them changed the overflow by 0px, because they
   were only following.

   The device tiles are excluded: mobile-fix.css already tunes `.top-block` and
   `.top-blockk` for the device board, and they are meant to sit several to a
   row rather than stack.
   --------------------------------------------------------------------------- */
@media (max-width: 991px) {
    .box,
    .box-content,
    .widget-content,
    #content,
    .row-fluid,
    .container-fluid,
    .well:not(.top-block):not(.top-blockk) {
        box-sizing: border-box !important;
    }

    /* a content panel must not be wider than the column that holds it */
    .box[class*="span"],
    .box-content,
    .widget-content,
    .well[class*="span"]:not(.top-block):not(.top-blockk) {
        max-width: 100% !important;
    }
}


/* ---------------------------------------------------------------------------
   6. Two causes found by elimination

   Edge-based blame could not find these: direction:rtl shifts every coordinate,
   and the layout viewport inflates (window.innerWidth measured 430 and 489
   against a 390px screen) so every fixed overlay reports the inflated width and
   looks guilty. Hiding one subtree at a time and watching scrollWidth found the
   real ones.

   (a) `div.controls` on the reservation form carries an inline
       `display: flex; flex-wrap: wrap` with `flex: 1` children. A flex item
       defaults to `min-width: auto`, so the text inputs would not shrink below
       their intrinsic width - the same trap as section 1, on a different
       element. gold-ps.xyz / control_reservations.php: 99px.

   (b) `div.box-content` on the day report carries an inline
       `margin-left: -40px`, which pulls the panel outside its container.
       ps-hub.online / reports_day.php: 35px. A negative horizontal margin on a
       content panel is never what you want on a phone, so it is zeroed below
       the desktop breakpoint only.
   --------------------------------------------------------------------------- */
@media (max-width: 991px) {
    /* (a) let the form row WRAP instead of crushing its fields.

       The children carry an inline `flex: 1`, i.e. a 0% basis, so with nothing
       else they all try to share one line: eight fields in a 378px row squeezed
       the wrappers to 12px and the inputs to 26px, their irreducible
       padding-plus-border minimum - still 14px over each parent, and unusable
       besides. The basis has to be raised, and because `flex: 1` is inline only
       !important can do it. With a ~160px basis and wrapping they lay out two to
       a row at a readable width and nothing overflows. */
    .controls {
        max-width: 100%;
        flex-wrap: wrap !important;
    }

    .controls > * {
        min-width: 0;
        flex: 1 1 160px !important;
    }

    .controls input,
    .controls select,
    .controls textarea {
        width: 100%;
        max-width: 100%;
        box-sizing: border-box;
    }

    /* (b) a panel pulled sideways by a negative margin */
    .box-content,
    .box > .box-content,
    .widget-content {
        margin-left: 0 !important;
        margin-right: 0 !important;
    }
}


/* ---------------------------------------------------------------------------
   7. The report date filter

   Nine pages per site (reports_day, reports_month, reports_year and their
   casheer_all / shift_all variants) carry this in a page <style> block:

       .form_control { display: flex; gap: 15px; justify-content: center; }
       span { width: 108px !important; }

   Two problems. The flex row has no flex-wrap, so the day / month / year
   inputs and the submit button are pinned in one line - measured on
   ykvip.shop at a 390px viewport, the `se_day` input alone reached x=798 and
   dragged the document 231px wide. And that `span` selector is unscoped and
   !important, so it forces every span on the page to 108px.

   Fixed here rather than in the pages because the block is duplicated across
   all nine, on every site. `.form_control span` outranks a bare `span`, so
   this wins over the inline !important regardless of load order.

   Confirmed pre-existing: measured with this layer blocked at the network and
   the overflow was the same 231px, so it is an old bug rather than one the
   responsive work introduced.
   --------------------------------------------------------------------------- */
.form_control {
    flex-wrap: wrap;
    max-width: 100%;
}

.form_control > * {
    min-width: 0;
}

@media (max-width: 991px) {
    .form_control span,
    .form_control select,
    .form_control input,
    .form_control label {
        width: auto !important;
        max-width: 100%;
    }

    /* Bootstrap 2 gives inputs fixed pixel widths by span class
       (input.span2 = 140px, input.span11 = 850px). None of those fit a phone. */
    input[class*="span"],
    select[class*="span"],
    textarea[class*="span"] {
        width: 100% !important;
        max-width: 100%;
    }
}
