/*
 * The mobile layer.
 *
 * The Velzon theme underneath is already responsive - the sidebar collapses, Bootstrap's grid
 * reflows, and tables inside .table-responsive scroll. What does not reflow is the custom layout
 * written directly into individual screens: two- and three-column CSS grids with a fixed minimum
 * column width, stat tiles with a min-width, side panes pinned to a pixel width. Below about
 * 400px those force the whole page sideways, and a page that scrolls horizontally is a page
 * nobody can use one-handed.
 *
 * This collapses them, in one place, rather than editing twenty views to say the same thing.
 *
 * Two deliberate decisions:
 *
 *   !important is used throughout. The grids being overridden are declared in <style> blocks
 *   inside the views themselves, which the browser sees after this file (head vs body), so an
 *   equal-specificity rule here would lose. This is the one case where !important is the correct
 *   tool rather than a shortcut.
 *
 *   The selectors are named rather than generic. There is no CSS way to say "any element that
 *   happens to be display:grid", so the list below was taken from the screens that actually
 *   declare a fixed-floor grid. A new screen that adds one needs a line here - or better, needs
 *   to use minmax(0, 1fr) so it never needed one.
 */

/* ==================================================================== tablet and below */

@media (max-width: 991.98px) {

    /* Three-column workspaces become two, then one further down. An editor squeezed next to a
       preview at tablet width is two things too narrow to use rather than one that works. */
    .email-studio,
    .elearning-grid,
    .content-grid {
        grid-template-columns: minmax(0, 1fr) !important;
    }

    .survey-layout,
    .events-workspace,
    .public-workspace,
    .checkin-workspace,
    .badge-card {
        grid-template-columns: minmax(0, 1fr) !important;
    }

    /* A side pane wider than the screen is a pane with its close button off the edge. */
    .offcanvas.offcanvas-end,
    .offcanvas.offcanvas-start {
        max-width: 100vw !important;
    }
}

/* ==================================================================== phone */

@media (max-width: 767.98px) {

    /* ---------------------------------------------------------------- page frame */

    /* Nothing should be able to push the page sideways. Applied to the scroll container rather
       than to body, so position:sticky headers inside it still work. */
    .main-content,
    .page-content {
        overflow-x: hidden;
    }

    .page-content {
        padding: 12px 0 40px;
    }

    .container-fluid {
        padding-left: 12px;
        padding-right: 12px;
    }

    .card-body {
        padding: 14px;
    }

    /* ---------------------------------------------------------------- custom grids */

    /* Every multi-column layout written into a screen. All of these declare a fixed minimum
       column width, which is what forces the horizontal scroll on a phone. */
    .assessment-row,
    .badge-card,
    .checkin-workspace,
    .content-grid,
    .content-layout,
    .course-grid,
    .doc-grid,
    .doc-library-grid,
    .elearning-grid,
    .email-studio,
    .event-cards,
    .events-workspace,
    .learner-grid,
    .project-tracking-grid,
    .public-workspace,
    .question-row-header,
    .quiz-layout,
    .result-bar,
    .result-hero,
    .sp-layout,
    .survey-layout {
        grid-template-columns: minmax(0, 1fr) !important;
    }

    /* Fixed panel heights make sense beside something; stacked they just leave dead space. */
    .sp-layout,
    .content-layout,
    .learner-grid,
    .email-studio {
        min-height: 0 !important;
    }

    .sp-list,
    .email-studio .email-canvas,
    .email-studio .email-compose textarea {
        max-height: 320px !important;
        min-height: 220px !important;
    }

    /* ---------------------------------------------------------------- stat tiles */

    /* Tiles sized to hold a number and a label side by side. On a phone they want to fill the
       row instead of forcing one. */
    .wsp-stat-tile,
    .project-stat-tile,
    .provider-stat-tile,
    .company-stat-tile {
        min-width: 0 !important;
        flex: 1 1 45% !important;
    }

    /* ---------------------------------------------------------------- tables */

    /* A table is the one thing that should scroll sideways rather than reflow - a timetable or a
       ledger stops meaning anything once its columns wrap. Give it its own scroll area and a
       readable size, and keep the page itself still. */
    .table-responsive {
        -webkit-overflow-scrolling: touch;
    }

    .table > :not(caption) > * > * {
        padding: 8px 10px;
    }

    .table {
        font-size: 13px;
    }

    /* ---------------------------------------------------------------- timetable */

    /* The week grid is seven columns wide by definition. Scrolling it is right; squashing it is
       not - a 40px column cannot hold a subject name.

       .tt-grid is both the scroll box and the grid, so the floor goes on the tracks rather than
       on the element: a min-width here would widen the box itself and hand the scroll back to
       the page. The tracks total ~740px, the box stays at whatever the screen allows, and the
       overflow-x it already carries does the rest. */
    .tt-grid {
        grid-template-columns: 56px repeat(7, minmax(98px, 1fr)) !important;
        -webkit-overflow-scrolling: touch;
    }

    /* ---------------------------------------------------------------- toolbars and actions */

    /* Rows of buttons that sit on one line on a desktop. Left alone they overflow; wrapped they
       simply take a second line. */
    .modern-table-toolbar,
    .card-header .d-flex,
    .d-flex.justify-content-between {
        flex-wrap: wrap;
        gap: 8px;
    }

    .modern-table-search {
        width: 100% !important;
        max-width: none !important;
    }

    /* A button that says what it does is worth a full row on a phone. */
    .card-header .btn-group,
    .modern-table-toolbar .btn {
        white-space: nowrap;
    }

    /* ---------------------------------------------------------------- tabs */

    /* Tab strips are the other thing that reliably overflows. Scroll them rather than wrap - a
       wrapped tab strip pushes the content it labels off the first screen. */
    .nav-tabs,
    .nav-pills {
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }

    .nav-tabs::-webkit-scrollbar,
    .nav-pills::-webkit-scrollbar {
        display: none;
    }

    .nav-tabs .nav-link,
    .nav-pills .nav-link {
        white-space: nowrap;
    }

    /* ---------------------------------------------------------------- modals */

    /* Bootstrap already pads a modal off the edges; the large variants still assume a desktop. */
    .modal-dialog.modal-lg,
    .modal-dialog.modal-xl {
        max-width: 100%;
        margin: 8px;
    }

    .modal-footer {
        flex-wrap: wrap;
        gap: 8px;
    }

    .modal-footer > .btn {
        flex: 1 1 auto;
    }

    /* ---------------------------------------------------------------- forms */

    /* Anything under 16px makes iOS zoom the page on focus, and it never zooms back out. */
    .form-control,
    .form-select,
    input[type="text"],
    input[type="email"],
    input[type="number"],
    input[type="password"],
    input[type="date"],
    textarea,
    select {
        font-size: 16px;
    }

    /* ---------------------------------------------------------------- media */

    img,
    iframe,
    video,
    canvas,
    embed,
    object {
        max-width: 100%;
    }

    /* Charts size themselves from their container and then refuse to shrink with it. */
    .apex-charts,
    .apexcharts-canvas {
        max-width: 100% !important;
    }
}

/* ==================================================================== small phone */

@media (max-width: 575.98px) {

    .wsp-stat-tile,
    .project-stat-tile,
    .provider-stat-tile,
    .company-stat-tile {
        flex: 1 1 100% !important;
    }

    /* Stacked action buttons, full width, in the order they read. */
    .modern-table-toolbar > div {
        width: 100%;
    }

    .modern-table-toolbar .btn {
        flex: 1 1 auto;
    }

    h4, .h4 { font-size: 17px; }
    h5, .h5 { font-size: 15px; }
}

/* ---------------------------------------------------------------------------
   Sidebar: the menu starts below the logo, not on top of it.

   The brand box holds a logo rendered at its natural 110-120px, which is far
   taller than the Velzon theme assumes. Combined with the negative top margin
   that used to sit on .app-menu, the logo was cropped at the top and the first
   menu item overlapped it. The markup no longer pulls the menu up; these rules
   give the brand box a definite height and cap the logo so it cannot grow back
   into the menu when a college supplies its own artwork.
   --------------------------------------------------------------------------- */
.navbar-menu .navbar-brand-box {
    display: flex !important;
    align-items: center;
    justify-content: center;
    padding: 1rem 1.3rem 0.75rem !important;
    margin-bottom: 0.5rem !important;
    /* A border rather than a gap: it reads as a deliberate divider between the
       brand and the navigation, and it makes any future overlap obvious. */
    border-bottom: 1px solid rgba(255, 255, 255, .08);
}

/* Branding is uploaded per college, so the cap is on the rendered element -
   an over-large upload gets scaled down instead of pushing the menu off-screen. */
.navbar-menu .navbar-brand-box .logo img {
    max-height: 72px;
    height: auto;
    width: auto;
    max-width: 100%;
    object-fit: contain;
}

/* Collapsed sidebar: the rail is about 70px wide, so the mark has to shrink
   with it rather than overflow the rail. */
:is([data-layout=vertical], [data-layout=semibox])[data-sidebar-size=sm] .navbar-menu .navbar-brand-box .logo img,
:is([data-layout=vertical], [data-layout=semibox])[data-sidebar-size=sm-hover] .navbar-menu .navbar-brand-box .logo img {
    max-height: 42px;
}

/* ==================================================================== the sidebar on a phone

   The menu was open on arrival on a phone: 250px of a ~400px screen, fixed-position, sitting
   on top of the page. Every screen opened with its own content hidden behind the navigation,
   and the only way to read anything was to know to tap the hamburger to dismiss a menu nobody
   asked for.

   This was written when the sidebar was a Syncfusion ejs-sidebar, whose inline width and
   transform beat the theme's own margin-left off-canvas rules and stopped them having any
   effect. The sidebar is plain markup now, so the theme's rules do work - but these are kept
   because they state the two states explicitly and are not at the mercy of a theme upgrade.
   They move the same element in the same direction as the theme's rules, so the two agree.

   The hamburger already toggles body.vertical-sidebar-enable, which is the class the theme
   uses, so nothing here needs new JavaScript. It only needs the two states to look different:
   off-canvas by default below the tablet breakpoint, on-canvas when that class is present. */

@media (max-width: 767.98px) {

    .app-menu.navbar-menu {
        transform: translateX(-100%) !important;
        transition: transform .2s ease !important;
    }

    body.vertical-sidebar-enable .app-menu.navbar-menu {
        transform: translateX(0) !important;
    }

    /* The overlay exists in the markup but is left display:none. Showing it does two jobs:
       it dims the page so the menu reads as a layer over it, and the theme already binds a
       click on it to close - so tapping anywhere outside dismisses the menu, which is what
       a phone user will try first. */
    body.vertical-sidebar-enable .vertical-overlay {
        display: block !important;
        position: fixed !important;
        inset: 0 !important;
        background: rgba(0, 0, 0, .45) !important;
        z-index: 1003 !important;
    }

    /* ---------------------------------------------------------------- page header */

    /* .page-title-box measured wider than the viewport on every screen, pushing the
       breadcrumb and any action button in it off the right edge. */
    .page-title-box {
        max-width: 100% !important;
        overflow: hidden !important;
    }
    .page-title-box .breadcrumb {
        flex-wrap: wrap !important;
    }

    /* ---------------------------------------------------------------- filter tabs */

    /*  Status tabs - All / New / Qualified / Offered / Waiting list / ... - ran past the
        right edge and were simply clipped, so the later ones could not be tapped at all
        on a phone. Scrolling the strip keeps every tab reachable; hiding the scrollbar
        keeps it from looking broken on a device that has no visible scrollbar anyway. */
    .nav-tabs,
    .nav-pills,
    .nav-tabs-custom {
        flex-wrap: nowrap !important;
        overflow-x: auto !important;
        overflow-y: hidden !important;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    .nav-tabs::-webkit-scrollbar,
    .nav-pills::-webkit-scrollbar,
    .nav-tabs-custom::-webkit-scrollbar { display: none; }

    .nav-tabs .nav-item,
    .nav-pills .nav-item,
    .nav-tabs-custom .nav-item { flex: 0 0 auto !important; }

    /* ---------------------------------------------------------------- tables */

    /*  Any table wider than the screen scrolls inside its own box rather than stretching
        the page. Applied to the table's own wrapper where a view forgot .table-responsive,
        which is most of the ones written before this file existed. */
    .card-body > .table,
    .card-body > table.table {
        display: block !important;
        overflow-x: auto !important;
        white-space: nowrap;
    }
}

/* ==================================================================== the top bar
 *
 * The theme's own topbar mostly behaves - the clock is d-xl, the icon buttons are d-sm - but
 * three things still broke on small screens: the ticker's space-around cut the first and last
 * figures once it overflowed, the icon buttons kept desktop spacing and crowded the bell
 * dropdowns off the edge at 360px, and a notification dropdown wider than the viewport opened
 * with its close half off-screen.
 */

@media (max-width: 991.98px) {

    /*  Anchored left once space is short: with space-around, an overflowing flex row clips
        both ends and the ZAR/USD figure - the one people look for - is the first casualty. */
    .cmis-ticker-track {
        justify-content: flex-start;
        gap: 1rem;
        padding: .3rem .75rem;
    }
}

@media (max-width: 767.98px) {

    .navbar-header {
        padding: 0 8px;
        gap: 2px;
    }

    /*  Desktop margins between icon buttons are what pushed the user card off the edge. */
    #page-topbar .header-item {
        margin-left: 0 !important;
    }

    #page-topbar .btn-topbar {
        height: 38px;
        width: 38px;
    }

    .topbar-user #page-header-user-dropdown {
        padding-left: 6px;
        padding-right: 6px;
    }

    /*  A dropdown panel may never be wider than the screen it opens on. */
    #page-topbar .dropdown-menu {
        max-width: calc(100vw - 16px);
    }
}

/* ==================================================================== generic phone safety */

@media (max-width: 767.98px) {

    /*  Dialogs breathe on a phone rather than touching both edges. */
    .modal-dialog:not(.modal-sm) {
        margin: .5rem auto;
        max-width: calc(100vw - 1rem);
    }

    /*  Title rows with actions on the right wrap instead of squeezing the title to nothing. */
    .page-title-box,
    .card-header {
        flex-wrap: wrap;
        row-gap: .5rem;
    }
}
